diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index d2d54979b7..6831e5563e 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -1891,3 +1891,98 @@ function drupal_common_theme() {
     ],
   ];
 }
+
+/**
+ * Returns HTML for a description list.
+ *
+ * "The dl element represents an association list consisting of zero or more
+ * name-value groups (a description list). Each group must consist of one or
+ * more names (dt elements) followed by one or more values (dd elements). Within
+ * a single dl element, there should not be more than one dt element for each
+ * name."
+ *
+ * This means:
+ * - The dl element may be empty.
+ * - If there is a dt element, it must be followed by a dd element.
+ * - There can be multiple dt elements followed by one or more dd element.
+ * - Each set of dt elements and dd elements forms a "group".
+ * - The text of one dt element must be unique within the dl element.
+ * - The dl element must contain dt and dd elements only.
+ *
+ * @see http://html5doctor.com/the-dl-element/
+ * @see http://www.w3.org/TR/html-markup/dl.html
+ * @see http://www.w3.org/wiki/HTML_lists#Description_lists
+ *
+ * @param array $variables
+ *   An associative array containing:
+ *   - groups: The list of groups to render. Each group is an array keyed by tag
+ *     name containing one of the following values:
+ *     - A simple string.
+ *     - An array of strings.
+ *     - A render array.
+ *     - An array of render arrays.
+ *     Each element will be wrapped in either a dt or dd element depending on
+ *     the key of the group array. When using render arrays it is possible to
+ *     use the #wrapper_attributes property to specify attributes for the dt/dd
+ *     element itself.
+ *   - attributes: Optional attributes to apply to the dl element.
+ *
+ * @return string
+ *   The rendered description list.
+*/
+function theme_description_list($variables) {
+  $items = array();
+
+  if (!isset($variables['attributes']['class'])) {
+    $variables['attributes']['class'] = array();
+  }
+  $variables['attributes']['class'][] = 'definition-list';
+
+  $output = '<dl' . new Attribute($variables['attributes']) . '>';
+
+  // A group is a set of zero or more dt and dd name-value pairs.
+  if (!empty($variables['groups'])) {
+    foreach ($variables['groups'] as $group) {
+      foreach ($group as $tag => $elements) {
+        // If the elements variable contains a string, there is only one dt/dd
+        // element.
+        if (is_string($elements)) {
+          $items[] = array(
+            'tag' => $tag,
+            'value' => $elements,
+            'attributes' => array(),
+          );
+        }
+        else {
+          // There are multiple dt/dd elements.
+          foreach ($elements as $value) {
+            if (is_string($value)) {
+              $items[] = array(
+                'tag' => $tag,
+                'value' => $value,
+                'attributes' => array(),
+              );
+            }
+            else {
+              // At this point we should be dealing with a render array.
+              $items[] = array(
+                'tag' => $tag,
+                'value' => drupal_render($value),
+                'attributes' => !empty($value['#wrapper_attributes']) ? $value['#wrapper_attributes'] : array(),
+              );
+            }
+          }
+        }
+      }
+    }
+  }
+
+  foreach ($items as $item) {
+    $attributes = new Attribute($item['attributes']);
+    $output .= '<' . $item['tag'] . $attributes . '>' . $item['value'] . '</' . $item['tag'] . '>';
+  }
+
+  $output .= '</dl>';
+
+  return $output;
+}
