diff --git a/core/includes/common.inc b/core/includes/common.inc
index 17f83ad..e15779f 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -6928,6 +6928,9 @@ function drupal_common_theme() {
     'hidden' => array(
       'render element' => 'element',
     ),
+    'autocomplete' => array(
+      'render element' => 'element',
+    ),
     'textfield' => array(
       'render element' => 'element',
     ),
diff --git a/core/includes/form.inc b/core/includes/form.inc
index 853990b..bbfa366 100644
--- a/core/includes/form.inc
+++ b/core/includes/form.inc
@@ -3631,6 +3631,52 @@ function theme_vertical_tabs($variables) {
 }
 
 /**
+ * Processes a form element with #autocomplete_path into a new 'autocomplete' child element.
+ *
+ * @param $element
+ *   The form element to process. Properties used:
+ *   - #autocomplete_path: A system path to be used as callback URL by the
+ *     autocomplete JavaScript library.
+ */
+function form_process_autocomplete($element, &$form_state) {
+  if (!empty($element['#autocomplete_path'])) {
+    $element['#attributes']['class'][] = 'form-autocomplete';
+    $element['#tree'] = TRUE;
+    $element['autocomplete'] = array(
+      '#type' => 'autocomplete',
+      '#value' => url($element['#autocomplete_path'], array('absolute' => TRUE)),
+      '#access' => drupal_valid_path($element['#autocomplete_path']),
+      '#attached' => array(
+        'library' => array(array('system', 'drupal.autocomplete')),
+      ),
+      '#attributes' => array(
+        'class' => array('autocomplete'),
+        'disabled' => 'disabled',
+      ),
+    );
+  }
+  return $element;
+}
+
+/**
+ * Returns HTML for an autocomplete form element.
+ *
+ * @param $variables
+ *   An associative array containing:
+ *   - element: An associative array containing the properties of the element.
+ *     Properties used: #id, #value, #attributes.
+ *
+ * @ingroup themeable
+ */
+function theme_autocomplete($variables) {
+  $element = $variables['element'];
+  $element['#attributes']['type'] = 'hidden';
+  element_set_attributes($element, array('id', 'value'));
+
+  return '<input' . drupal_attributes($element['#attributes']) . ' />' . drupal_render_children($element);
+}
+
+/**
  * Returns HTML for a submit button form element.
  *
  * @param $variables
@@ -3720,7 +3766,7 @@ function theme_hidden($variables) {
  *   An associative array containing:
  *   - element: An associative array containing the properties of the element.
  *     Properties used: #title, #value, #description, #size, #maxlength,
- *     #placeholder, #required, #attributes, #autocomplete_path.
+ *     #placeholder, #required, #attributes.
  *
  * @ingroup themeable
  */
@@ -3730,23 +3776,7 @@ function theme_textfield($variables) {
   element_set_attributes($element, array('id', 'name', 'value', 'size', 'maxlength', 'placeholder'));
   _form_set_class($element, array('form-text'));
 
-  $extra = '';
-  if ($element['#autocomplete_path'] && drupal_valid_path($element['#autocomplete_path'])) {
-    drupal_add_library('system', 'drupal.autocomplete');
-    $element['#attributes']['class'][] = 'form-autocomplete';
-
-    $attributes = array();
-    $attributes['type'] = 'hidden';
-    $attributes['id'] = $element['#attributes']['id'] . '-autocomplete';
-    $attributes['value'] = url($element['#autocomplete_path'], array('absolute' => TRUE));
-    $attributes['disabled'] = 'disabled';
-    $attributes['class'][] = 'autocomplete';
-    $extra = '<input' . drupal_attributes($attributes) . ' />';
-  }
-
-  $output = '<input' . drupal_attributes($element['#attributes']) . ' />';
-
-  return $output . $extra;
+  return '<input' . drupal_attributes($element['#attributes']) . ' />' . drupal_render_children($element);
 }
 
 /**
@@ -3756,7 +3786,7 @@ function theme_textfield($variables) {
  *   An associative array containing:
  *   - element: An associative array containing the properties of the element.
  *     Properties used: #title, #value, #description, #size, #maxlength,
- *     #placeholder, #required, #attributes, #autocomplete_path.
+ *     #placeholder, #required, #attributes.
  *
  * @ingroup themeable
  */
@@ -3766,23 +3796,7 @@ function theme_tel($variables) {
   element_set_attributes($element, array('id', 'name', 'value', 'size', 'maxlength', 'placeholder'));
   _form_set_class($element, array('form-tel'));
 
-  $extra = '';
-  if ($element['#autocomplete_path'] && drupal_valid_path($element['#autocomplete_path'])) {
-    drupal_add_library('system', 'drupal.autocomplete');
-    $element['#attributes']['class'][] = 'form-autocomplete';
-
-    $attributes = array();
-    $attributes['type'] = 'hidden';
-    $attributes['id'] = $element['#attributes']['id'] . '-autocomplete';
-    $attributes['value'] = url($element['#autocomplete_path'], array('absolute' => TRUE));
-    $attributes['disabled'] = 'disabled';
-    $attributes['class'][] = 'autocomplete';
-    $extra = '<input' . drupal_attributes($attributes) . ' />';
-  }
-
-  $output = '<input' . drupal_attributes($element['#attributes']) . ' />';
-
-  return $output . $extra;
+  return '<input' . drupal_attributes($element['#attributes']) . ' />' . drupal_render_children($element);
 }
 
 /**
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index 7fc0141..df81321 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -361,7 +361,7 @@ function system_element_info() {
     '#size' => 60,
     '#maxlength' => 128,
     '#autocomplete_path' => FALSE,
-    '#process' => array('ajax_process_form'),
+    '#process' => array('form_process_autocomplete', 'ajax_process_form'),
     '#theme' => 'textfield',
     '#theme_wrappers' => array('form_element'),
   );
@@ -370,7 +370,7 @@ function system_element_info() {
     '#size' => 30,
     '#maxlength' => 128,
     '#autocomplete_path' => FALSE,
-    '#process' => array('ajax_process_form'),
+    '#process' => array('form_process_autocomplete', 'ajax_process_form'),
     '#theme' => 'tel',
     '#theme_wrappers' => array('form_element'),
   );
@@ -381,7 +381,7 @@ function system_element_info() {
     '#maxlength' => 64,
     '#size' => 60,
     '#autocomplete_path' => FALSE,
-    '#process' => array('form_process_machine_name', 'ajax_process_form'),
+    '#process' => array('form_process_machine_name', 'form_process_autocomplete', 'ajax_process_form'),
     '#element_validate' => array('form_validate_machine_name'),
     '#theme' => 'textfield',
     '#theme_wrappers' => array('form_element'),
@@ -506,6 +506,10 @@ function system_element_info() {
     '#default_tab' => '',
     '#process' => array('form_process_vertical_tabs'),
   );
+  $types['autocomplete'] = array(
+    '#process' => array('ajax_process_form'),
+    '#theme' => 'autocomplete',
+  );
 
   $types['container'] = array(
     '#theme_wrappers' => array('container'),
