diff --git a/django/forms/fields.py b/django/forms/fields.py
index ea93c306c5..762d59c1b9 100644
--- a/django/forms/fields.py
+++ b/django/forms/fields.py
@@ -204,6 +204,14 @@ class Field(six.with_metaclass(RenameFieldMethods, object)):
         data_value = data if data is not None else ''
         return initial_value != data_value
 
+    def get_bound_field(self, form, field_name):
+        """
+        Return a BoundField instance that will be used when accessing the form
+        field in a template.
+        """
+        from django.forms.forms import BoundField
+        return BoundField(form, self, field_name)
+
     def __deepcopy__(self, memo):
         result = copy.copy(self)
         memo[id(self)] = result
diff --git a/django/forms/forms.py b/django/forms/forms.py
index 7db2465fda..07415f8fe1 100644
--- a/django/forms/forms.py
+++ b/django/forms/forms.py
@@ -152,7 +152,7 @@ class BaseForm(object):
             raise KeyError(
                 "Key %r not found in '%s'" % (name, self.__class__.__name__))
         if name not in self._bound_fields_cache:
-            self._bound_fields_cache[name] = BoundField(self, field, name)
+            self._bound_fields_cache[name] = field.get_bound_field(self, name)
         return self._bound_fields_cache[name]
 
     @property
diff --git a/docs/ref/forms/api.txt b/docs/ref/forms/api.txt
index 16e8443361..ca9e4d868f 100644
--- a/docs/ref/forms/api.txt
+++ b/docs/ref/forms/api.txt
@@ -932,6 +932,48 @@ and using the template above, would render something like:
 
     <label for="myFIELD">...</label><input id="myFIELD" type="text" name="my_field" />
 
+Customizing ``BoundField``
+--------------------------
+
+.. versionadded:: 1.9
+
+If you need to access some additional information about a form field in a
+template and using a subclass of :class:`~django.forms.Field` isn't
+sufficient, consider also customizing :class:`~django.forms.BoundField`.
+
+A custom form field can override ``get_bound_field()``:
+
+.. method:: Field.get_bound_field(form, field_name)
+
+    Takes an instance of :class:`~django.forms.Form` and the name of the field.
+    The return value will be used when accessing the field in a template. Most
+    likely it will be an instance of a subclass of
+    :class:`~django.forms.BoundField`.
+
+If you have a ``GPSCoordinatesField``, for example, and want to be able to
+access additional information about the coordinates in a template, this could
+be implemented as follows::
+
+    class GPSCoordinatesBoundField(BoundField):
+        @property
+        def country(self):
+            """
+            Return the country the coordinates lie in or None if it can't be
+            determined.
+            """
+            value = self.value()
+            if value:
+                return get_country_from_coordinates(value)
+            else:
+                return None
+
+    class GPSCoordinatesField(Field):
+        def get_bound_field(self, form, field_name):
+            return GPSCoordinatesBoundField(form, self, field_name)
+
+Now you can access the country in a template with
+``{{ form.coordinates.country }}``.
+
 .. _binding-uploaded-files:
 
 Binding uploaded files to a form
diff --git a/docs/ref/forms/fields.txt b/docs/ref/forms/fields.txt
index 88c35829c0..ac7c6400ae 100644
--- a/docs/ref/forms/fields.txt
+++ b/docs/ref/forms/fields.txt
@@ -1239,3 +1239,6 @@ custom ``Field`` classes. To do this, just create a subclass of
 ``clean()`` method and that its ``__init__()`` method accept the core arguments
 mentioned above (``required``, ``label``, ``initial``, ``widget``,
 ``help_text``).
+
+You can also customize how a field will be accessed by overriding
+:meth:`~django.forms.Field.get_bound_field()`.
diff --git a/docs/releases/1.9.txt b/docs/releases/1.9.txt
index 73b2cffb8c..d5ed37737f 100644
--- a/docs/releases/1.9.txt
+++ b/docs/releases/1.9.txt
@@ -364,6 +364,9 @@ Forms
 * Form fields now support the :attr:`~django.forms.Field.disabled` argument,
   allowing the field widget to be displayed disabled by browsers.
 
+* It's now possible to customize bound fields by overriding a field's
+  :meth:`~django.forms.Field.get_bound_field()` method.
+
 Generic Views
 ^^^^^^^^^^^^^
 
diff --git a/tests/forms_tests/tests/test_forms.py b/tests/forms_tests/tests/test_forms.py
index ac96d775a2..d3618b1a8c 100644
--- a/tests/forms_tests/tests/test_forms.py
+++ b/tests/forms_tests/tests/test_forms.py
@@ -1903,6 +1903,17 @@ Password: <input type="password" name="password" /></li>
         f = SampleForm(data={'name': 'bar'})
         self.assertIsInstance(force_text(f['name']), SafeData)
 
+    def test_custom_boundfield(self):
+        class CustomField(CharField):
+            def get_bound_field(self, form, name):
+                return (form, name)
+
+        class SampleForm(Form):
+            name = CustomField()
+
+        f = SampleForm()
+        self.assertEqual(f['name'], (f, 'name'))
+
     def test_initial_datetime_values(self):
         now = datetime.datetime.now()
         # Nix microseconds (since they should be ignored). #22502