diff --git a/django/contrib/admin/templates/registration/password_reset_subject.txt b/django/contrib/admin/templates/registration/password_reset_subject.txt
new file mode 100644
--- /dev/null
+++ b/django/contrib/admin/templates/registration/password_reset_subject.txt
@@ -0,0 +1,3 @@
+{% load i18n %}{% autoescape off %}
+{% blocktrans %}Password reset on {{ site_name }}{% endblocktrans %}
+{% endautoescape %}
\ No newline at end of file
diff --git a/django/contrib/auth/fixtures/authtestdata.json b/django/contrib/auth/fixtures/authtestdata.json
--- a/django/contrib/auth/fixtures/authtestdata.json
+++ b/django/contrib/auth/fixtures/authtestdata.json
@@ -31,7 +31,7 @@
             "groups": [], 
             "user_permissions": [], 
             "password": "sha1$6efc0$f93efe9fd7542f25a7be94871ea45aa95de57161", 
-            "email": "testclient@example.com", 
+            "email": "testclient2@example.com",
             "date_joined": "2006-12-17 07:03:31"
         }
     },
diff --git a/django/contrib/auth/forms.py b/django/contrib/auth/forms.py
--- a/django/contrib/auth/forms.py
+++ b/django/contrib/auth/forms.py
@@ -117,8 +117,11 @@
             raise forms.ValidationError(_("That e-mail address doesn't have an associated user account. Are you sure you've registered?"))
         return email
 
-    def save(self, domain_override=None, email_template_name='registration/password_reset_email.html',
-             use_https=False, token_generator=default_token_generator, from_email=None, request=None):
+    def save(self, domain_override=None,
+             subject_template_name='registration/password_reset_subject.txt',
+             email_template_name='registration/password_reset_email.html',
+             use_https=False, token_generator=default_token_generator,
+             from_email=None, request=None):
         """
         Generates a one-use only link for resetting password and sends to the user
         """
@@ -130,7 +133,6 @@
                 domain = current_site.domain
             else:
                 site_name = domain = domain_override
-            t = loader.get_template(email_template_name)
             c = {
                 'email': user.email,
                 'domain': domain,
@@ -140,8 +142,10 @@
                 'token': token_generator.make_token(user),
                 'protocol': use_https and 'https' or 'http',
             }
-            send_mail(_("Password reset on %s") % site_name,
-                t.render(Context(c)), from_email, [user.email])
+            subject = loader.render_to_string(subject_template_name, c)
+            subject = ''.join(subject.splitlines())
+            email = loader.render_to_string(email_template_name, c)
+            send_mail(subject, email, from_email, [user.email])
 
 class SetPasswordForm(forms.Form):
     """
diff --git a/django/contrib/auth/tests/forms.py b/django/contrib/auth/tests/forms.py
--- a/django/contrib/auth/tests/forms.py
+++ b/django/contrib/auth/tests/forms.py
@@ -242,6 +242,23 @@
         self.assertTrue(form.is_valid())
         self.assertEqual(form.cleaned_data['email'], u'jsmith3@example.com')
 
+    def test_custom_email_subject(self):
+        import os
+        from django.conf import settings
+        from django.core import mail
+
+        old_TEMPLATE_DIRS = settings.TEMPLATE_DIRS
+        settings.TEMPLATE_DIRS = (os.path.join(os.path.dirname(__file__), 'templates'),)
+        data = {'email': 'testclient@example.com'}
+        form = PasswordResetForm(data)
+        try:
+            self.assertTrue(form.is_valid())
+            form.save()
+
+            self.assertEqual(len(mail.outbox), 1)
+            self.assertEqual(mail.outbox[0].subject, u'Custom password reset on example.com')
+        finally:
+            settings.TEMPLATE_DIRS = old_TEMPLATE_DIRS
 
     def test_bug_5605(self):
         # bug #5605, preserve the case of the user name (before the @ in the
diff --git a/django/contrib/auth/tests/templates/registration/password_reset_subject.txt b/django/contrib/auth/tests/templates/registration/password_reset_subject.txt
new file mode 100644
--- /dev/null
+++ b/django/contrib/auth/tests/templates/registration/password_reset_subject.txt
@@ -0,0 +1,3 @@
+{% load i18n %}{% autoescape off %}
+{% blocktrans %}Custom password reset on {{ site_name }}{% endblocktrans %}
+{% endautoescape %}
diff --git a/django/contrib/auth/views.py b/django/contrib/auth/views.py
--- a/django/contrib/auth/views.py
+++ b/django/contrib/auth/views.py
@@ -128,7 +128,8 @@
                    post_reset_redirect=None,
                    from_email=None,
                    current_app=None,
-                   extra_context=None):
+                   extra_context=None,
+                   subject_template_name='registration/password_reset_subject.txt'):
     if post_reset_redirect is None:
         post_reset_redirect = reverse('django.contrib.auth.views.password_reset_done')
     if request.method == "POST":
@@ -140,6 +141,7 @@
                 'from_email': from_email,
                 'email_template_name': email_template_name,
                 'request': request,
+                'subject_template_name': subject_template_name,
             }
             if is_admin_site:
                 opts = dict(opts, domain_override=request.META['HTTP_HOST'])
diff --git a/django/core/management/commands/makemessages.py b/django/core/management/commands/makemessages.py
--- a/django/core/management/commands/makemessages.py
+++ b/django/core/management/commands/makemessages.py
@@ -356,7 +356,7 @@
         if domain == 'djangojs':
             extensions = handle_extensions(extensions or ['js'])
         else:
-            extensions = handle_extensions(extensions or ['html'])
+            extensions = handle_extensions(extensions or ['html', 'txt'])
 
         if verbosity > 1:
             sys.stdout.write('examining files with the extensions: %s\n'
