diff --git a/django/template/defaultfilters.py b/django/template/defaultfilters.py
index 865f5fe..19a73ad 100644
--- a/django/template/defaultfilters.py
+++ b/django/template/defaultfilters.py
@@ -16,7 +16,7 @@ from django.utils.html import (conditional_escape, escapejs, fix_ampersands,
     escape, urlize as _urlize, linebreaks, strip_tags, avoid_wrapping,
     remove_tags)
 from django.utils.http import urlquote
-from django.utils.text import Truncator, wrap, phone2numeric
+from django.utils.text import Truncator, wrap, phone2numeric, word_capital
 from django.utils.safestring import mark_safe, SafeData, mark_for_escaping
 from django.utils import six
 from django.utils.timesince import timesince, timeuntil
@@ -266,6 +266,15 @@ def title(value):
 
 @register.filter(is_safe=True)
 @stringfilter
+def wordcap(value):
+    """
+    Capitalizes the first character of each word.
+    """
+    return word_capital(value)
+
+
+@register.filter(is_safe=True)
+@stringfilter
 def truncatechars(value, arg):
     """
     Truncates a string after a certain number of characters.
diff --git a/django/utils/text.py b/django/utils/text.py
index f52050c..8a63ed7 100644
--- a/django/utils/text.py
+++ b/django/utils/text.py
@@ -29,6 +29,18 @@ re_newlines = re.compile(r'\r\n|\r')  # Used in normalize_newlines
 re_camel_case = re.compile(r'(((?<=[a-z])[A-Z])|([A-Z](?![A-Z]|$)))')
 
 
+def word_capital(text):
+    """
+    Capitalizes the first character of each word, it converts a string into
+    titlecase by making words start with an uppercase character and keep the
+    remaining characters.
+    """
+    if text and len(text) > 0:
+        return ' '.join([s[0].upper() + s[1:] for s in text.split(' ') if len(s) > 0])
+    else:
+        return text
+
+
 def wrap(text, width):
     """
     A word-wrap function that preserves existing line breaks and most spaces in
diff --git a/docs/ref/templates/builtins.txt b/docs/ref/templates/builtins.txt
index e5c6efc..b92383a 100644
--- a/docs/ref/templates/builtins.txt
+++ b/docs/ref/templates/builtins.txt
@@ -1214,6 +1214,21 @@ For example::
 
 If ``value`` is ``"django"``, the output will be ``"Django"``.
 
+.. templatefilter:: wordcap
+
+wordcap
+^^^^^^^
+
+Capitalizes the first character of each word, it converts a string into
+titlecase by making words start with an uppercase character and keep the
+remaining characters.
+
+For example::
+
+    {{ value|wordcap }}
+
+If ``value`` is ``"joel SMS content"``, the output will be ``"Joel SMS Content"``.
+
 .. templatefilter:: center
 
 center
diff --git a/tests/defaultfilters/tests.py b/tests/defaultfilters/tests.py
index 2dc6d9c..af0de04 100644
--- a/tests/defaultfilters/tests.py
+++ b/tests/defaultfilters/tests.py
@@ -14,7 +14,7 @@ from django.template.defaultfilters import (
     phone2numeric_filter, pluralize, removetags, rjust, slice_filter, slugify,
     stringformat, striptags, time, timesince_filter, timeuntil_filter, title,
     truncatewords, truncatewords_html, unordered_list, upper, urlencode,
-    urlize, urlizetrunc, wordcount, wordwrap, yesno,
+    urlize, urlizetrunc, wordcount, wordwrap, yesno, wordcap,
 )
 from django.test import TestCase
 from django.test.utils import TransRealMixin
@@ -111,6 +111,9 @@ class DefaultFiltersTests(TestCase):
     def test_capfirst(self):
         self.assertEqual(capfirst('hello world'), 'Hello world')
 
+    def test_wordcap(self):
+        self.assertEqual(wordcap('send SMS'), 'Send SMS')
+
     def test_escapejs(self):
         self.assertEqual(escapejs_filter('"double quotes" and \'single quotes\''),
             '\\u0022double quotes\\u0022 and \\u0027single quotes\\u0027')
diff --git a/tests/template_tests/tests.py b/tests/template_tests/tests.py
index 0afb3a8..8df0599 100644
--- a/tests/template_tests/tests.py
+++ b/tests/template_tests/tests.py
@@ -1503,6 +1503,9 @@ class TemplateTests(TransRealMixin, TestCase):
             'i18n38': ('{% load i18n custom %}{% get_language_info for "de"|noop:"x y" as l %}{{ l.code }}: {{ l.name }}/{{ l.name_local }} bidi={{ l.bidi }}', {}, 'de: German/Deutsch bidi=False'),
             'i18n38_2': ('{% load i18n custom %}{% get_language_info_list for langcodes|noop:"x y" as langs %}{% for l in langs %}{{ l.code }}: {{ l.name }}/{{ l.name_local }} bidi={{ l.bidi }}; {% endfor %}', {'langcodes': ['it', 'no']}, 'it: Italian/italiano bidi=False; no: Norwegian/norsk bidi=False; '),
 
+            # test wordcap with the {% trans %} tag
+            'i18n39': ("{% load i18n %}{% trans 'Page not found'|wordcap %}", {'LANGUAGE_CODE': 'de'}, 'Seite Nicht Gefunden'),
+
             ### HANDLING OF TEMPLATE_STRING_IF_INVALID ###################################
 
             'invalidstr01': ('{{ var|default:"Foo" }}', {}, ('Foo', 'INVALID')),
