diff --git a/core/includes/common.inc b/core/includes/common.inc
index 14154af..845b38b 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -7019,6 +7019,9 @@ function drupal_common_theme() {
     'range' => array(
       'render element' => 'element',
     ),
+    'color' => array(
+      'render element' => 'element',
+    ),
     'form' => array(
       'render element' => 'element',
     ),
diff --git a/core/includes/form.inc b/core/includes/form.inc
index c387384..5bdaf90 100644
--- a/core/includes/form.inc
+++ b/core/includes/form.inc
@@ -5,6 +5,8 @@
  * Functions for form and batch generation and processing.
  */
 
+use Drupal\Core\Utility\Color;
+
 /**
  * @defgroup forms Form builder functions
  * @{
@@ -4086,6 +4088,45 @@ function form_validate_url(&$element, &$form_state) {
 }
 
 /**
+ * Form element validation handler for #type 'color'.
+ */
+function form_validate_color(&$element, &$form_state) {
+  // Empty means black.
+  $value = trim($element['#value']);
+  if ($value === '') {
+    $value = '#000000';
+  }
+
+  // Try to parse the value.
+  if ($parsed = Color::parseHex($value)) {
+    // Set a normalized value.
+    form_set_value($element, $parsed->__toString(), $form_state);
+  }
+  else {
+    form_error($element, t('%name must be a valid color.', array('%name' => empty($element['#title']) ? $element['#parents'][0] : $element['#title'])));
+  }
+}
+
+/**
+ * Returns HTML for a color form element.
+ *
+ * @param $variables
+ *   An associative array containing:
+ *   - element: An associative array containing the properties of the element.
+ *     Properties used: #title, #value, #description, #attributes.
+ *
+ * @ingroup themeable
+ */
+function theme_color($variables) {
+  $element = $variables['element'];
+  $element['#attributes']['type'] = 'color';
+  element_set_attributes($element, array('id', 'name', 'value'));
+  _form_set_class($element, array('form-color'));
+
+  return '<input' . drupal_attributes($element['#attributes']) . ' />' . drupal_render_children($element);
+}
+
+/**
  * Returns HTML for a form.
  *
  * @param $variables
diff --git a/core/lib/Drupal/Core/Utility/Color.php b/core/lib/Drupal/Core/Utility/Color.php
new file mode 100644
index 0000000..ec30fb0
--- /dev/null
+++ b/core/lib/Drupal/Core/Utility/Color.php
@@ -0,0 +1,131 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\Core\Utility\Color.
+ */
+
+namespace Drupal\Core\Utility;
+
+/**
+ * Represents a color.
+ */
+class Color {
+
+  /**
+   * The red component of the color as an integer between 0 and 255.
+   *
+   * @var int
+   */
+  protected $red;
+
+  /**
+   * The green component of the color as an integer between 0 and 255.
+   *
+   * @var int
+   */
+  protected $green;
+
+  /**
+   * The blue component of the color as an integer between 0 and 255.
+   *
+   * @var int
+   */
+  protected $blue;
+
+  /**
+   * Constructs a Color object.
+   *
+   * @param int $red
+   *   The red component of the color as an integer between 0 and 255.
+   * @param int $green
+   *   The green component of the color as an integer between 0 and 255.
+   * @param int $blue
+   *   The blue component of the color as an integer between 0 and 255.
+   *
+   * @throws \InvalidArgumentException
+   *   When one of the components has an invalid value.
+   */
+  public function __construct($red, $green, $blue) {
+    if ($red < 0 || $green < 0 || $blue < 0 || $red > 255 || $green > 255 || $blue > 255) {
+      throw new \InvalidArgumentException('Color components must be integers between 0 and 255.');
+    }
+
+    $this->red = (int) $red;
+    $this->green = (int) $green;
+    $this->blue = (int) $blue;
+  }
+
+  /**
+   * Implements PHP magic __toString method to convert the color to a string.
+   *
+   * @return string
+   *   A hexadecimal representation of the color like '#aabbcc' or '#aabbcc55'.
+   */
+  public function __toString() {
+    $result = '#';
+
+    foreach (array('red', 'green', 'blue', 'alpha') as $component) {
+      if ($component != 'alpha' || $this->{$component}) {
+        $result .= str_pad(dechex($this->{$component}), 2, '0', STR_PAD_LEFT);
+      }
+    }
+
+    return $result;
+  }
+
+  /**
+   * Gets the red component of the color.
+   *
+   * @return int
+   *   The red component of the color as an integer between 0 and 255.
+   */
+  public function getRed() {
+    return $this->red;
+  }
+
+  /**
+   * Gets the green component of the color.
+   *
+   * @return int
+   *   The green component of the color as an integer between 0 and 255.
+   */
+  public function getGreen() {
+    return $this->green;
+  }
+
+  /**
+   * Gets the blue component of the color.
+   *
+   * @return int
+   *   The blue component of the color as an integer between 0 and 255.
+   */
+  public function getBlue() {
+    return $this->blue;
+  }
+
+  /**
+   * Parses a hexadecimal color string like '#abc' or '#aabbcc'.
+   *
+   * @param string $hex
+   *   The hexadecimal colorstring to parse.
+   *
+   * @return false|Drupal\Core\Utility\Color
+   *   The color object representation of the string or FALSE, if the string is
+   *   invalid.
+   */
+  public static function parseHex($hex) {
+    $hex = ltrim($hex, '#');
+
+    // Expand shorthands like 'abc' to 'aabbcc'.
+    if (strlen($hex) < 4) {
+      $hex = preg_replace('|([0-9a-f])|i', '\1\1', $hex);
+    }
+
+    if (!preg_match('/^([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i', $hex, $rgb)) {
+      return FALSE;
+    }
+
+    return new Color(hexdec($rgb[1]), hexdec($rgb[2]), hexdec($rgb[3]));
+  }
+}
diff --git a/core/modules/simpletest/drupal_web_test_case.php b/core/modules/simpletest/drupal_web_test_case.php
index 23fa526..6d563f5 100644
--- a/core/modules/simpletest/drupal_web_test_case.php
+++ b/core/modules/simpletest/drupal_web_test_case.php
@@ -2321,6 +2321,7 @@ class DrupalWebTestCase extends DrupalTestCase {
           case 'url':
           case 'number':
           case 'range':
+          case 'color':
           case 'hidden':
           case 'password':
           case 'email':
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index 69ee2af..8d5f09e 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -425,6 +425,14 @@ function system_element_info() {
     '#theme' => 'range',
     '#theme_wrappers' => array('form_element'),
   );
+  $types['color'] = array(
+    '#input' => TRUE,
+    '#default_value' => '#000000',
+    '#process' => array('ajax_process_form'),
+    '#element_validate' => array('form_validate_color'),
+    '#theme' => 'color',
+    '#theme_wrappers' => array('form_element'),
+  );
   $types['machine_name'] = array(
     '#input' => TRUE,
     '#default_value' => NULL,
diff --git a/core/modules/system/tests/form.test b/core/modules/system/tests/form.test
index b64fdd7..3e31dc7 100644
--- a/core/modules/system/tests/form.test
+++ b/core/modules/system/tests/form.test
@@ -366,6 +366,41 @@ class FormsTestCase extends DrupalWebTestCase {
   }
 
   /**
+   * Tests validation of #type 'color' elements.
+   */
+  function testColorValidation() {
+    // Keys are inputs, values are expected results.
+    $values = array(
+      '' => '#000000',
+      '#000' => '#000000',
+      'AAA' => '#aaaaaa',
+      '#af0DEE' => '#af0dee',
+      '#99ccBc' => '#99ccbc',
+      '#aabbcc' => '#aabbcc',
+      '123456' => '#123456',
+    );
+
+    // Tests that valid values are properly normalized.
+    foreach ($values as $input => $expected) {
+      $edit = array(
+        'color' => $input,
+      );
+      $result = json_decode($this->drupalPost('form-test/color', $edit, 'Submit'));
+      $this->assertEqual($result->color, $expected);
+    }
+
+    // Tests invalid values are rejected.
+    $values = array('#0008', '#1234', '#fffffg', '#abcdef22', '17', '#uaa');
+    foreach ($values as $input) {
+      $edit = array(
+        'color' => $input,
+      );
+      $this->drupalPost('form-test/color', $edit, 'Submit');
+      $this->assertRaw(t('%name must be a valid color.', array('%name' => 'Color')));
+    }
+  }
+
+  /**
    * Test handling of disabled elements.
    *
    * @see _form_test_disabled_elements()
@@ -408,7 +443,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), 39, 'The correct elements have the disabled property in the HTML code.');
+    $this->assertEqual(count($disabled_elements), 40, '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/system/tests/modules/form_test/form_test.module b/core/modules/system/tests/modules/form_test/form_test.module
index f42b5f5..141c6d0 100644
--- a/core/modules/system/tests/modules/form_test/form_test.module
+++ b/core/modules/system/tests/modules/form_test/form_test.module
@@ -145,6 +145,12 @@ function form_test_menu() {
     'page arguments' => array('form_test_number', 'range'),
     'access callback' => TRUE,
   );
+  $items['form-test/color'] = array(
+    'title' => 'Color',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('form_test_color'),
+    'access callback' => TRUE,
+  );
   $items['form-test/checkboxes-radios'] = array(
     'title' => t('Checkboxes, Radios'),
     'page callback' => 'drupal_get_form',
@@ -1277,6 +1283,32 @@ function form_test_number($form, &$form_state, $element = 'number') {
 }
 
 /**
+ * Form constructor for testing #type 'color' elements.
+ *
+ * @see form_test_color_submit()
+ * @ingroup forms
+ */
+function form_test_color($form, &$form_state) {
+  $form['color'] = array(
+    '#type' => 'color',
+    '#title' => 'Color',
+  );
+  $form['submit'] = array(
+    '#type' => 'submit',
+    '#value' => 'Submit',
+  );
+  return $form;
+}
+
+/**
+ * Form submission handler for form_test_color().
+ */
+function form_test_color_submit($form, &$form_state) {
+  drupal_json_output($form_state['values']);
+  exit;
+}
+
+/**
  * Builds a form to test the placeholder attribute.
  */
 function form_test_placeholder_test($form, &$form_state) {
@@ -1496,6 +1528,16 @@ function _form_test_disabled_elements($form, &$form_state) {
     );
   }
 
+  // Color.
+  $form['color'] = array(
+    '#type' => 'color',
+    '#title' => 'color',
+    '#disabled' => TRUE,
+    '#default_value' => '#0000ff',
+    '#test_hijack_value' => '#ff0000',
+    '#disabled' => TRUE,
+  );
+
   // Date.
   $form['date'] = array(
     '#type' => 'date',
diff --git a/core/themes/bartik/css/style.css b/core/themes/bartik/css/style.css
index 7ab3d4e..3563b44 100644
--- a/core/themes/bartik/css/style.css
+++ b/core/themes/bartik/css/style.css
@@ -1194,6 +1194,7 @@ input.form-email,
 input.form-url,
 input.form-search,
 input.form-number,
+input.form-color,
 textarea.form-textarea,
 select.form-select {
   border: 1px solid #ccc;
diff --git a/core/themes/seven/style.css b/core/themes/seven/style.css
index a3d6773..9e807d5 100644
--- a/core/themes/seven/style.css
+++ b/core/themes/seven/style.css
@@ -612,6 +612,7 @@ div.teaser-checkbox .form-item,
 .form-disabled input.form-url,
 .form-disabled input.form-search,
 .form-disabled input.form-number,
+.form-disabled input.form-color,
 .form-disabled input.form-file,
 .form-disabled textarea.form-textarea,
 .form-disabled select.form-select {
@@ -703,6 +704,7 @@ input.form-email,
 input.form-url,
 input.form-search,
 input.form-number,
+input.form-color,
 input.form-file,
 textarea.form-textarea,
 select.form-select {
@@ -721,6 +723,7 @@ input.form-email:focus,
 input.form-url:focus,
 input.form-search:focus,
 input.form-number:focus,
+input.form-color:focus,
 input.form-file:focus,
 textarea.form-textarea:focus,
 select.form-select:focus {
