diff --git a/modules/field/field.api.php b/modules/field/field.api.php
index 68784d13a75edb61fcb33dbb134fec170e834bc9..88f9231ac8ce711cee6e21b17a52c2859e40a0ed 100644
--- a/modules/field/field.api.php
+++ b/modules/field/field.api.php
@@ -675,10 +675,6 @@ function hook_field_is_empty($item, $field) {
  * Widget hooks are typically called by the Field Attach API during the
  * creation of the field form structure with field_attach_form().
  *
- * @see hook_field_widget_info_alter()
- * @see hook_field_widget_form()
- * @see hook_field_widget_error()
- *
  * @return
  *   An array describing the widget types implemented by the module.
  *   The keys are widget type names. To avoid name clashes, widget type
@@ -704,6 +700,12 @@ function hook_field_is_empty($item, $field) {
  *       - FIELD_BEHAVIOR_DEFAULT: (default) If the widget accepts default
  *         values.
  *       - FIELD_BEHAVIOR_NONE: if the widget does not support default values.
+ *
+ * @see hook_field_widget_info_alter()
+ * @see hook_field_widget_form()
+ * @see hook_field_widget_form_alter()
+ * @see hook_field_widget_WIDGET_TYPE_form_alter()
+ * @see hook_field_widget_error()
  */
 function hook_field_widget_info() {
     return array(
@@ -783,8 +785,8 @@ function hook_field_widget_info_alter(&$info) {
  * properties from $field and $instance and set them as ad-hoc
  * $element['#custom'] properties, for later use by its element callbacks.
  *
- * @see field_widget_field()
- * @see field_widget_instance()
+ * Other modules may alter the form element provided by this function using
+ * hook_field_widget_form_alter().
  *
  * @param $form
  *   The form structure where widgets are being attached to. This might be a
@@ -826,6 +828,11 @@ function hook_field_widget_info_alter(&$info) {
  *
  * @return
  *   The form elements for a single widget for this field.
+ *
+ * @see field_widget_field()
+ * @see field_widget_instance()
+ * @see hook_field_widget_form_alter()
+ * @see hook_field_widget_WIDGET_TYPE_form_alter()
  */
 function hook_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
   $element += array(
@@ -835,6 +842,69 @@ function hook_field_widget_form(&$form, &$form_state, $field, $instance, $langco
   return $element;
 }
 
+/**
+ * Alter forms for field widgets provided by other modules.
+ *
+ * @param $element
+ *   The field widget form element as constructed by hook_field_widget_form().
+ * @param $form_state
+ *   An associative array containing the current state of the form.
+ * @param $context
+ *   An associative array containing the following key-value pairs, matching the
+ *   arguments received by hook_field_widget_form():
+ *   - "form": The form structure where widgets are being attached to. This
+ *     might be a full form structure, or a sub-element of a larger form.
+ *   - "field": The field structure.
+ *   - "instance": The field instance structure.
+ *   - "langcode": The language associated with $items.
+ *   - "items": Array of default values for this field.
+ *   - "delta": The order of this item in the array of subelements (0, 1, 2,
+ *     etc).
+ *
+ * @see hook_field_widget_form()
+ * @see hook_field_widget_WIDGET_TYPE_form_alter
+ */
+function hook_field_widget_form_alter(&$element, &$form_state, $context) {
+  // Add a css class to widget form elements for all fields of type mytype.
+  if ($context['field']['type'] == 'mytype') {
+    // Be sure not to overwrite existing attributes.
+    $element['#attributes']['class'][] = 'myclass';
+  }
+}
+
+/**
+ * Alter widget forms for a specific widget provided by another module.
+ *
+ * Modules can implement hook_field_widget_WIDGET_TYPE_form_alter() to modify a
+ * specific widget form, rather than using hook_field_widget_form_alter() and
+ * checking the widget type.
+ *
+ * @param $element
+ *   The field widget form element as constructed by hook_field_widget_form().
+ * @param $form_state
+ *   An associative array containing the current state of the form.
+ * @param $context
+ *   An associative array containing the following key-value pairs, matching the
+ *   arguments received by hook_field_widget_form():
+ *   - "form": The form structure where widgets are being attached to. This
+ *     might be a full form structure, or a sub-element of a larger form.
+ *   - "field": The field structure.
+ *   - "instance": The field instance structure.
+ *   - "langcode": The language associated with $items.
+ *   - "items": Array of default values for this field.
+ *   - "delta": The order of this item in the array of subelements (0, 1, 2,
+ *     etc).
+ *
+ * @see hook_field_widget_form()
+ * @see hook_field_widget_form_alter()
+ */
+function hook_field_widget_WIDGET_TYPE_form_alter(&$element, &$form_state, $context) {
+  // Code here will only act on widgets of type WIDGET_TYPE.  For example,
+  // hook_field_widget_mymodule_autocomplete_form_alter() will only act on
+  // widgets of type 'mymodule_autocomplete'.
+  $element['#autocomplete_path'] = 'mymodule/autocomplete_path';
+}
+
 /**
  * Flag a field-level validation error.
  *
diff --git a/modules/field/field.form.inc b/modules/field/field.form.inc
index 640ea75ec08ff6dc774d0c3dabe541a041602c14..79fc14a20e87c4324e6d6193984f2e395ff9c802 100644
--- a/modules/field/field.form.inc
+++ b/modules/field/field.form.inc
@@ -76,6 +76,17 @@ function field_default_form($entity_type, $entity, $field, $instance, $langcode,
           '#delta' => $delta,
         );
         if ($element = $function($form, $form_state, $field, $instance, $langcode, $items, $delta, $element)) {
+          // Allow modules to alter the field widget form element.
+          $context = array(
+            'form' => $form,
+            'field' => $field,
+            'instance' => $instance,
+            'langcode' => $langcode,
+            'items' => $items,
+            'delta' => $delta,
+          );
+          drupal_alter(array('field_widget_form', 'field_widget_' . $instance['widget']['type'] . '_form'), $element, $form_state, $context);
+
           // If we're processing a specific delta value for a field where the
           // field module handles multiples, set the delta in the result.
           // For fields that handle their own processing, we can't make
@@ -193,6 +204,18 @@ function field_multiple_value_form($field, $instance, $langcode, $items, &$form,
             '#weight' => 100,
           );
         }
+
+        // Allow modules to alter the field widget form element.
+        $context = array(
+          'form' => $form,
+          'field' => $field,
+          'instance' => $instance,
+          'langcode' => $langcode,
+          'items' => $items,
+          'delta' => $delta,
+        );
+        drupal_alter(array('field_widget_form', 'field_widget_' . $instance['widget']['type'] . '_form'), $element, $form_state, $context);
+
         $field_elements[$delta] = $element;
       }
     }