diff --git a/django/utils/translation/trans_real.py b/django/utils/translation/trans_real.py
index 195badfc00..789d59e2ba 100644
--- a/django/utils/translation/trans_real.py
+++ b/django/utils/translation/trans_real.py
@@ -285,7 +285,8 @@ def pgettext(context, message):
     result = ugettext(msg_with_ctxt)
     if CONTEXT_SEPARATOR in result:
         # Translation not found
-        result = message
+        # force unicode, because lazy version expects unicode
+        result = force_text(message)
     return result
 
 def gettext_noop(message):
diff --git a/docs/releases/1.6.5.txt b/docs/releases/1.6.5.txt
index 9abe6702cc..3c46b953b7 100644
--- a/docs/releases/1.6.5.txt
+++ b/docs/releases/1.6.5.txt
@@ -11,3 +11,6 @@ Bugfixes
 
 * Made the ``year_lookup_bounds_for_datetime_field`` Oracle backend method
   Python 3 compatible (`#22551 <http://code.djangoproject.com/ticket/22551>`_).
+
+* Fixed ``pgettext_lazy`` crash when receiving bytestring content on Python 2
+  (`#22565 <http://code.djangoproject.com/ticket/22565>`_).
diff --git a/tests/i18n/tests.py b/tests/i18n/tests.py
index a0bbd4f7d7..9533baac17 100644
--- a/tests/i18n/tests.py
+++ b/tests/i18n/tests.py
@@ -33,6 +33,7 @@ from django.utils.translation import (activate, deactivate,
     pgettext, pgettext_lazy,
     npgettext, npgettext_lazy,
     check_for_language)
+from django.utils.unittest import skipUnless
 
 if find_command('xgettext'):
     from .commands.extraction import (ExtractorTests, BasicExtractorTests,
@@ -88,9 +89,20 @@ class TranslationTests(TransRealMixin, TestCase):
         s4 = ugettext_lazy('Some other string')
         self.assertEqual(False, s == s4)
 
-        if six.PY2:
-            # On Python 2, gettext_lazy should not transform a bytestring to unicode
-            self.assertEqual(gettext_lazy(b"test").upper(), b"TEST")
+    @skipUnless(six.PY2, "No more bytestring translations on PY3")
+    def test_lazy_and_bytestrings(self):
+        # On Python 2, (n)gettext_lazy should not transform a bytestring to unicode
+        self.assertEqual(gettext_lazy(b"test").upper(), b"TEST")
+        self.assertEqual((ngettext_lazy(b"%d test", b"%d tests") % 1).upper(), b"1 TEST")
+
+        # Other versions of lazy functions always return unicode
+        self.assertEqual(ugettext_lazy(b"test").upper(), "TEST")
+        self.assertEqual((ungettext_lazy(b"%d test", b"%d tests") % 1).upper(), "1 TEST")
+        self.assertEqual(pgettext_lazy(b"context", b"test").upper(), "TEST")
+        self.assertEqual(
+            (npgettext_lazy(b"context", b"%d test", b"%d tests") % 1).upper(),
+            "1 TEST"
+        )
 
     def test_lazy_pickle(self):
         s1 = ugettext_lazy("test")