diff --git a/django/templatetags/cache.py b/django/templatetags/cache.py
index 387dd87..1b1b2be 100644
--- a/django/templatetags/cache.py
+++ b/django/templatetags/cache.py
@@ -1,9 +1,7 @@
 from django.template import Library, Node, TemplateSyntaxError, Variable, VariableDoesNotExist
 from django.template import resolve_variable
 from django.core.cache import cache
-from django.utils.encoding import force_unicode
-from django.utils.http import urlquote
-from django.utils.hashcompat import md5_constructor
+from django.utils.cache import get_template_cache_key
 
 register = Library()
 
@@ -24,8 +22,8 @@ class CacheNode(Node):
         except (ValueError, TypeError):
             raise TemplateSyntaxError('"cache" tag got a non-integer timeout value: %r' % expire_time)
         # Build a unicode key for this fragment and all vary-on's.
-        args = md5_constructor(u':'.join([urlquote(resolve_variable(var, context)) for var in self.vary_on]))
-        cache_key = 'template.cache.%s.%s' % (self.fragment_name, args.hexdigest())
+        args = [resolve_variable(var, context) for var in self.vary_on]
+        cache_key = get_template_cache_key(self.fragment_name, args)
         value = cache.get(cache_key)
         if value is None:
             value = self.nodelist.render(context)
diff --git a/django/utils/cache.py b/django/utils/cache.py
index 6cfd893..4c360f6 100644
--- a/django/utils/cache.py
+++ b/django/utils/cache.py
@@ -23,10 +23,9 @@ import time
 from django.conf import settings
 from django.core.cache import cache
 from django.utils.encoding import smart_str, iri_to_uri
-from django.utils.http import http_date
+from django.utils.http import http_date, urlquote
 from django.utils.hashcompat import md5_constructor
 from django.utils.translation import get_language
-from django.http import HttpRequest
 
 cc_delim_re = re.compile(r'\s*,\s*')
 
@@ -135,7 +134,14 @@ def patch_vary_headers(response, newheaders):
     response['Vary'] = ', '.join(vary_headers + additional_headers)
 
 def _i18n_cache_key_suffix(request, cache_key):
-    """If enabled, returns the cache key ending with a locale."""
+    """
+    If I18N is enabled, returns the cache key appended with a locale (otherwise
+    returns the cache key unmodified).
+
+    While ``request`` is a required argument, if it does not make sense in the
+    context of the key generation, use ``None`` for its value.
+
+    """
     if settings.USE_I18N:
         # first check if LocaleMiddleware or another middleware added
         # LANGUAGE_CODE to request, then fall back to the active language
@@ -210,6 +216,12 @@ def learn_cache_key(request, response, cache_timeout=None, key_prefix=None):
         cache.set(cache_key, [], cache_timeout)
         return _generate_cache_key(request, [], key_prefix)
 
+def get_template_cache_key(name, args=None):
+    """Returns a cache key for a template tag related cache."""
+    args = args and [urlquote(arg) for arg in args] or []
+    md5_args = md5_constructor(u':'.join(args))
+    cache_key = 'template.cache.%s.%s' % (name, md5_args.hexdigest())
+    return _i18n_cache_key_suffix(request=None, cache_key=cache_key)
 
 def _to_tuple(s):
     t = s.split('=',1)
diff --git a/tests/regressiontests/cache/tests.py b/tests/regressiontests/cache/tests.py
index 109374c..09ce616 100644
--- a/tests/regressiontests/cache/tests.py
+++ b/tests/regressiontests/cache/tests.py
@@ -16,8 +16,11 @@ from django.core.cache.backends.base import InvalidCacheBackendError
 from django.http import HttpResponse, HttpRequest
 from django.middleware.cache import FetchFromCacheMiddleware, UpdateCacheMiddleware
 from django.utils import translation
-from django.utils.cache import patch_vary_headers, get_cache_key, learn_cache_key
+from django.utils.cache import patch_vary_headers, get_cache_key, learn_cache_key,\
+    get_template_cache_key
 from django.utils.hashcompat import md5_constructor
+from django.template import Context
+from django.template.loader import get_template_from_string
 from regressiontests.cache.models import Poll, expensive_calculation
 
 # functions/classes for complex data type tests
@@ -527,7 +530,7 @@ class CacheI18nTest(unittest.TestCase):
         key2 = get_cache_key(request)
         self.assertEqual(key, key2)
 
-    def test_cache_key_no_i18n (self):
+    def test_cache_key_no_i18n(self):
         settings.USE_I18N = False
         request = self._get_request()
         lang = translation.get_language()
@@ -568,5 +571,35 @@ class CacheI18nTest(unittest.TestCase):
         get_cache_data = FetchFromCacheMiddleware().process_request(request)
         self.assertEqual(get_cache_data.content, es_message)
 
+    def test_template_cache_key_i18n(self):
+        settings.USE_I18N = True
+        lang = 'en'
+        translation.activate(lang)
+        key = get_template_cache_key('somekey')
+        self.assertTrue(key.endswith(lang), "Cache keys should include the "
+                        "language name when i18n is active")
+
+    def test_template_cache_key_no_i18n(self):
+        settings.USE_I18N = False
+        lang = 'en'
+        translation.activate(lang)
+        key = get_template_cache_key('somekey')
+        self.assertFalse(key.endswith(lang), "Cache keys shouldn't include "
+                         "the language name when i18n is inactive")
+
+    def test_template_tag(self):
+        settings.USE_I18N = True
+        template = get_template_from_string('{% load cache %}'
+                    '{% cache 60 greeting %}{{ welcome }}!{% endcache %}')
+        translation.activate('en')
+        template.render(Context({'welcome': 'Hello'}))
+        translation.activate('es')
+        template.render(Context({'welcome': 'Hola'}))
+
+        translation.activate('en')
+        self.assertEqual(template.render(Context()), 'Hello!')
+        translation.activate('es')
+        self.assertEqual(template.render(Context()), 'Hola!')
+
 if __name__ == '__main__':
     unittest.main()
