diff --git a/docsite/latest/rst/playbooks2.rst b/docsite/latest/rst/playbooks2.rst
index afb87e76043..8557e1cf53d 100644
--- a/docsite/latest/rst/playbooks2.rst
+++ b/docsite/latest/rst/playbooks2.rst
@@ -461,6 +461,33 @@ from turning into arbitrary code with ugly nested ifs, conditionals, and so on -
 in more streamlined & auditable configuration rules -- especially because there are a
 minimum of decision points to track.
 
+Do/Until
+````````
+
+Sometimes you would want to retry a task till a certain condition is met, In such conditions the Do/Until feature will help.
+Here's an example which show's the syntax to be applied for the task.
+
+    - action: shell /usr/bin/foo
+      register: result
+      until: register.stdout.find("all systems go") != -1
+      retries: 5
+      delay: 10
+
+The above example run the shell module recursively till the module's result has "all systems go" in it's stdout or the task has 
+been retried for 5 times with a delay of 10 seconds. The default value for "retries" is 3 and "delay" is 5.
+
+The task returns the results returned by the last task run. The results of individual retries can be viewed by -vv option.
+The results will have a new key "attempts" which will have the number of the retries for the task.
+
+.. note::
+    The Do/Until does not take decision on whether to fail or pass the play when the maximum retries are completed, the user can
+    can do that in the next task as follows:
+    
+    - name: fail the play
+      fail: msg=" This play fails as the foo exceeded maximum retries"
+      fail_when: register.attempts >= 5
+
+
 Loops
 `````
 
diff --git a/lib/ansible/runner/__init__.py b/lib/ansible/runner/__init__.py
index 0dc2fbf73e8..396dfeee083 100644
--- a/lib/ansible/runner/__init__.py
+++ b/lib/ansible/runner/__init__.py
@@ -654,7 +654,6 @@ class Runner(object):
 
         result = handler.run(conn, tmp, module_name, module_args, inject, complex_args)
         # Code for do until feature
-        until_result = 1
         until = self.module_vars.get('until', None)
         if until is not None and result.comm_ok:
             inject[self.module_vars.get('register')] = result.result
@@ -662,23 +661,22 @@ class Runner(object):
             if not utils.check_conditional(cond,  self.basedir, inject, fail_on_undefined=self.error_on_undefined_vars):
                 retries = self.module_vars.get('retries')
                 delay   = self.module_vars.get('delay')
-                for x in range(0, retries):
+                for x in range(1, retries + 1):
                     time.sleep(delay)
                     tmp = ''
                     if getattr(handler, 'NEEDS_TMPPATH', True):
                         tmp = self._make_tmp_path(conn)
                     result = handler.run(conn, tmp, module_name, module_args, inject, complex_args)
+                    result.result['attempts'] = x
                     vv("Result from run %i is: %s" % (x, result.result))
                     if not result.comm_ok:
                         break;
                     inject[self.module_vars.get('register')] = result.result
                     cond = template.template(self.basedir, until, inject, expand_lists=False)
                     if utils.check_conditional(cond, self.basedir, inject, fail_on_undefined=self.error_on_undefined_vars):
-                        until_result = 1
                         break;
-                    else:
-                        until_result = 0
-            result.result['until_result'] = until_result
+            else:
+                result.result['attempts'] = 0
         conn.close()
 
         if not result.comm_ok: