diff --git a/core/includes/common.inc b/core/includes/common.inc
index 967a596..cecbe99 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -6797,6 +6797,9 @@ function drupal_common_theme() {
     'textfield' => array(
       'render element' => 'element',
     ),
+    'tel' => array(
+      'render element' => 'element',
+    ),
     'form' => array(
       'render element' => 'element',
     ),
diff --git a/core/includes/form.inc b/core/includes/form.inc
index 3469377..5663ac6 100644
--- a/core/includes/form.inc
+++ b/core/includes/form.inc
@@ -3723,6 +3723,42 @@ function theme_textfield($variables) {
 }
 
 /**
+ * Returns HTML for a tel form element.
+ *
+ * @param $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.
+ *
+ * @ingroup themeable
+ */
+function theme_tel($variables) {
+  $element = $variables['element'];
+  $element['#attributes']['type'] = 'tel';
+  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;
+}
+
+/**
  * Returns HTML for a form.
  *
  * @param $variables
diff --git a/core/modules/simpletest/drupal_web_test_case.php b/core/modules/simpletest/drupal_web_test_case.php
index cdab966..7d59e9f 100644
--- a/core/modules/simpletest/drupal_web_test_case.php
+++ b/core/modules/simpletest/drupal_web_test_case.php
@@ -2226,6 +2226,7 @@ class DrupalWebTestCase extends DrupalTestCase {
       if (isset($edit[$name])) {
         switch ($type) {
           case 'text':
+          case 'tel':
           case 'textarea':
           case 'hidden':
           case 'password':
diff --git a/core/modules/simpletest/tests/form.test b/core/modules/simpletest/tests/form.test
index 94dfa87..784da88 100644
--- a/core/modules/simpletest/tests/form.test
+++ b/core/modules/simpletest/tests/form.test
@@ -37,6 +37,9 @@ class FormsTestCase extends DrupalWebTestCase {
     $elements['textfield']['element'] = array('#title' => $this->randomName(), '#type' => 'textfield');
     $elements['textfield']['empty_values'] = $empty_strings;
 
+    $elements['telephone']['element'] = array('#title' => $this->randomName(), '#type' => 'tel');
+    $elements['telephone']['empty_values'] = $empty_strings;
+
     $elements['password']['element'] = array('#title' => $this->randomName(), '#type' => 'password');
     $elements['password']['empty_values'] = $empty_strings;
 
@@ -258,7 +261,7 @@ class FormsTestCase extends DrupalWebTestCase {
 
     // All the elements should be marked as disabled, including the ones below
     // the disabled container.
-    $this->assertEqual(count($disabled_elements), 32, t('The correct elements have the disabled property in the HTML code.'));
+    $this->assertEqual(count($disabled_elements), 33, t('The correct elements have the disabled property in the HTML code.'));
 
     $this->drupalPost(NULL, $edit, t('Submit'));
     $returned_values['hijacked'] = drupal_json_decode($this->content);
diff --git a/core/modules/simpletest/tests/form_test.module b/core/modules/simpletest/tests/form_test.module
index 5e3fb17..e1e2435 100644
--- a/core/modules/simpletest/tests/form_test.module
+++ b/core/modules/simpletest/tests/form_test.module
@@ -1027,7 +1027,7 @@ function form_test_select_submit($form, &$form_state) {
  * Builds a form to test the placeholder attribute.
  */
 function form_test_placeholder_test($form, &$form_state) {
-  foreach (array('textfield', 'textarea', 'password') as $type) {
+  foreach (array('textfield', 'textarea', 'password', 'tel') as $type) {
     $form[$type] = array(
       '#type' => $type,
       '#title' => $type,
@@ -1102,7 +1102,7 @@ function form_test_checkboxes_radios($form, &$form_state, $customize = FALSE) {
  */
 function _form_test_disabled_elements($form, &$form_state) {
   // Elements that take a simple default value.
-  foreach (array('textfield', 'textarea', 'hidden') as $type) {
+  foreach (array('textfield', 'textarea', 'tel', 'hidden') as $type) {
     $form[$type] = array(
       '#type' => $type,
       '#title' => $type,
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index 20607d4..a0080dc 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -368,6 +368,15 @@ function system_element_info() {
     '#theme' => 'textfield',
     '#theme_wrappers' => array('form_element'),
   );
+  $types['tel'] = array(
+    '#input' => TRUE,
+    '#size' => 60,
+    '#maxlength' => 128,
+    '#autocomplete_path' => FALSE,
+    '#process' => array('ajax_process_form'),
+    '#theme' => 'tel',
+    '#theme_wrappers' => array('form_element'),
+  );
   $types['machine_name'] = array(
     '#input' => TRUE,
     '#default_value' => NULL,
