diff --git a/django/core/urlresolvers.py b/django/core/urlresolvers.py
index a35287e..52d9090 100644
--- a/django/core/urlresolvers.py
+++ b/django/core/urlresolvers.py
@@ -15,7 +15,7 @@ from django.conf import settings
 from django.core.exceptions import ImproperlyConfigured, ViewDoesNotExist
 from django.utils.datastructures import MultiValueDict
 from django.utils.encoding import iri_to_uri, force_unicode, smart_str
-from django.utils.functional import memoize
+from django.utils.functional import memoize, lazy
 from django.utils.importlib import import_module
 from django.utils.regex_helper import normalize
 
@@ -390,6 +390,8 @@ def reverse(viewname, urlconf=None, args=None, kwargs=None, prefix=None, current
     return iri_to_uri(u'%s%s' % (prefix, resolver.reverse(view,
             *args, **kwargs)))
 
+reverse_lazy = lazy(reverse, str)
+
 def clear_url_caches():
     global _resolver_cache
     global _callable_cache
diff --git a/docs/topics/http/urls.txt b/docs/topics/http/urls.txt
index 091dcb0..c82226a 100644
--- a/docs/topics/http/urls.txt
+++ b/docs/topics/http/urls.txt
@@ -815,6 +815,22 @@ namespaces into URLs on specific application instances, according to the
     be imported correctly. Do not include lines that reference views you
     haven't written yet, because those views will not be importable.
 
+reverse_lazy()
+--------------
+
+.. versionadded:: 1.3
+
+A lazily evaluated version of `reverse()`_.
+
+It is useful for when you need to use a URL reversal before Django's URL names
+map is loaded. Some common cases where this method is necessary are:
+
+* in your URL configuration (such as the ``url`` argument for the
+  ``django.views.generic.simple.redirect_to`` generic view).
+
+* providing a reversed URL to a decorator (such as the ``login_url`` argument
+  for the ``django.contrib.auth.decorators.permission_required`` decorator).
+
 resolve()
 ---------
 
diff --git a/tests/regressiontests/urlpatterns_reverse/reverse_lazy_urls.py b/tests/regressiontests/urlpatterns_reverse/reverse_lazy_urls.py
new file mode 100644
index 0000000..aa9d0f2
--- /dev/null
+++ b/tests/regressiontests/urlpatterns_reverse/reverse_lazy_urls.py
@@ -0,0 +1,10 @@
+from django.conf.urls.defaults import *
+from django.core.urlresolvers import reverse_lazy
+from django.views.generic.simple import redirect_to
+
+from views import empty_view
+
+urlpatterns = patterns('',
+    url(r'^$', empty_view, name='named-lazy-url-1'),
+    url(r'^redirect/$', redirect_to, dict(url=reverse_lazy('named-lazy-url-1'))),
+)
diff --git a/tests/regressiontests/urlpatterns_reverse/tests.py b/tests/regressiontests/urlpatterns_reverse/tests.py
index 198d556..48b03d9 100644
--- a/tests/regressiontests/urlpatterns_reverse/tests.py
+++ b/tests/regressiontests/urlpatterns_reverse/tests.py
@@ -218,6 +218,13 @@ class ResolverTests(unittest.TestCase):
                         else:
                             self.assertEqual(t.name, e['name'], 'Wrong URL name.  Expected "%s", got "%s".' % (e['name'], t.name))
 
+class ReverseLazyTest(TestCase):
+    urls = 'regressiontests.urlpatterns_reverse.reverse_lazy_urls'
+
+    def test_redirect_with_lazy_reverse(self):
+        response = self.client.get('/redirect/')
+        self.assertRedirects(response, "/", status_code=301)
+
 class ReverseShortcutTests(TestCase):
     urls = 'regressiontests.urlpatterns_reverse.urls'

