diff --git a/lib/ansible/playbook/play_context.py b/lib/ansible/playbook/play_context.py
index f5ea8aeb79..db46a25474 100644
--- a/lib/ansible/playbook/play_context.py
+++ b/lib/ansible/playbook/play_context.py
@@ -134,6 +134,18 @@ SU_PROMPT_LOCALIZATIONS = [
     '密碼',
 ]
 
+TASK_ATTRIBUTE_OVERRIDES = (
+    'become',
+    'become_user',
+    'become_pass',
+    'become_method',
+    'connection',
+    'delegate_to',
+    'no_log',
+    'remote_user',
+)
+
+
 class PlayContext(Base):
 
     '''
@@ -285,7 +297,7 @@ class PlayContext(Base):
 
         # loop through a subset of attributes on the task object and set
         # connection fields based on their values
-        for attr in ('connection', 'remote_user', 'become', 'become_user', 'become_pass', 'become_method', 'no_log'):
+        for attr in TASK_ATTRIBUTE_OVERRIDES:
             if hasattr(task, attr):
                 attr_val = getattr(task, attr)
                 if attr_val is not None:
diff --git a/lib/ansible/plugins/action/synchronize.py b/lib/ansible/plugins/action/synchronize.py
index 031a2b0e97..11171d3e03 100644
--- a/lib/ansible/plugins/action/synchronize.py
+++ b/lib/ansible/plugins/action/synchronize.py
@@ -75,13 +75,10 @@ class ActionModule(ActionBase):
 
         original_transport = task_vars.get('ansible_connection') or self._play_context.connection
         transport_overridden = False
-        if task_vars.get('delegate_to') is None:
-            task_vars['delegate_to'] = '127.0.0.1'
-            # IF original transport is not local, override transport and disable sudo.
-            if original_transport != 'local':
-                task_vars['ansible_connection'] = 'local'
-                transport_overridden = True
-                self._play_context.become = False
+        try:
+            delegate_to = self._play_context.delegate_to
+        except (AttributeError, KeyError):
+            delegate_to = None
 
         use_ssh_args = self._task.args.pop('use_ssh_args', None)
 
@@ -103,13 +100,15 @@ class ActionModule(ActionBase):
         # CHECK DELEGATE HOST INFO
         use_delegate = False
 
-        if dest_host == task_vars.get('delegate_to'):
+        if dest_host == delegate_to:
             # edge case: explicit delegate and dest_host are the same
+            # so we run rsync on the remote machine targetting its localhost
+            # (itself)
             dest_host = '127.0.0.1'
             use_delegate = True
         else:
             if 'hostvars' in task_vars:
-                if task_vars.get('delegate_to') in task_vars['hostvars'] and original_transport != 'local':
+                if delegate_to in task_vars['hostvars'] and original_transport != 'local':
                     # use a delegate host instead of localhost
                     use_delegate = True
 
@@ -126,12 +125,19 @@ class ActionModule(ActionBase):
         # Delegate to localhost as the source of the rsync unless we've been
         # told (via delegate_to) that a different host is the source of the
         # rsync
-        if not use_delegate:
+        transport_overridden = False
+        if not use_delegate and original_transport != 'local':
             # Create a connection to localhost to run rsync on
-            ### FIXME: Do we have to dupe stdin or is this sufficient?
             new_stdin = self._connection._new_stdin
             new_connection = connection_loader.get('local', self._play_context, new_stdin)
             self._connection = new_connection
+            transport_overridden = True
+            ### FIXME: We think that this was here for v1 because the local
+            # connection didn't support sudo.  In v2 it does so we think it's
+            # safe to remove this now.
+
+            # Also disable sudo
+            #self._play_context.become = False
 
         # MUNGE SRC AND DEST PER REMOTE_HOST INFO
         src  = self._task.args.get('src', None)
@@ -140,10 +146,11 @@ class ActionModule(ActionBase):
 
             user = None
             if boolean(task_vars.get('set_remote_user', 'yes')):
+                if use_delegate:
+                    user = task_vars['hostvars'][delegate_to].get('ansible_ssh_user')
+
                 if not use_delegate or not user:
                     user = task_vars.get('ansible_ssh_user') or self._play_context.remote_user
-                elif use_delegate:
-                    user = task_vars['hostvars'][task_vars.get('delegate_to')].get('ansible_ssh_user')
 
             if use_delegate:
                 private_key = task_vars.get('ansible_ssh_private_key_file') or self._play_context.private_key_file