Fixed issue #2756
diff --git a/requests/models.py b/requests/models.py
index 4270c647eb..06e843623e 100644
--- a/requests/models.py
+++ b/requests/models.py
@@ -414,7 +414,7 @@ def prepare_body(self, data, files, json=None):
         content_type = None
         length = None
 
-        if json is not None:
+        if data == {} and json is not None:
             content_type = 'application/json'
             body = complexjson.dumps(json)
 
@@ -443,7 +443,7 @@ def prepare_body(self, data, files, json=None):
             if files:
                 (body, content_type) = self._encode_files(files, data)
             else:
-                if data and json is None:
+                if data:
                     body = self._encode_params(data)
                     if isinstance(data, basestring) or hasattr(data, 'read'):
                         content_type = None
diff --git a/test_requests.py b/test_requests.py
index 28ea5730d8..b5be37fc83 100755
--- a/test_requests.py
+++ b/test_requests.py
@@ -1062,6 +1062,13 @@ def test_json_param_post_content_type_works(self):
         assert 'application/json' in r.request.headers['Content-Type']
         assert {'life': 42} == r.json()['json']
 
+    def test_json_param_post_should_not_override_data_param(self):
+        r = requests.Request(method='POST', url='http://httpbin.org/post',
+                             data={'stuff': 'elixr'},
+                             json={'music': 'flute'})
+        prep = r.prepare()
+        assert 'stuff=elixr' == prep.body
+
     def test_response_iter_lines(self):
         r = requests.get(httpbin('stream/4'), stream=True)
         assert r.status_code == 200

Now 'json' parameter will be used to prepare body only if the 'data'
parameter is not present
