diff --git a/core/includes/form.inc b/core/includes/form.inc
index a12fb34..e2dfc27 100644
--- a/core/includes/form.inc
+++ b/core/includes/form.inc
@@ -1727,6 +1727,7 @@ function form_builder($form_id, &$element, &$form_state) {
     '#required' => FALSE,
     '#attributes' => array(),
     '#title_display' => 'before',
+    '#description_display' => 'after',
   );
 
   // Special handling if we're on the top level form element.
@@ -3837,7 +3838,9 @@ function theme_file($variables) {
  * - form-disabled: Only set if the form element is #disabled.
  *
  * In addition to the element itself, the DIV contains a label for the element
- * based on the optional #title_display property, and an optional #description.
+ * based on the optional #title_display property, and an optional #description,
+ * that can be output before or after the field depending on the
+ * #description_display property.
  *
  * The optional #title_display property can have these values:
  * - before: The label is output before the element. This is the default.
@@ -3863,11 +3866,18 @@ function theme_file($variables) {
  * but the parent element should have neither. Use this carefully because a
  * field without an associated label can cause accessibility challenges.
  *
+ * The optional #description_display property can have these values:
+ *  - before: The description is output before the element.
+ *  - after: The description is output after the element.
+ *
+ * If the #description property is not set, the description will not be output,
+ * regardless of the #description_display value.
+ *
  * @param $variables
  *   An associative array containing:
  *   - element: An associative array containing the properties of the element.
- *     Properties used: #title, #title_display, #description, #id, #required,
- *     #children, #type, #name.
+ *     Properties used: #title, #title_display, #description, #description_display,
+ *     #id, #required, #children, #type, #name.
  *
  * @ingroup themeable
  */
@@ -3880,6 +3890,7 @@ function theme_form_element($variables) {
   // may not necessarily have been processed by form_builder().
   $element += array(
     '#title_display' => 'before',
+    '#description_display' => 'after',
   );
 
   // Add element #id for #type 'item'.
@@ -3911,10 +3922,16 @@ function theme_form_element($variables) {
     case 'before':
     case 'invisible':
       $output .= ' ' . theme('form_element_label', $variables);
+      if (!empty($element['#description']) && $element['#description_display'] == 'before') {
+        $output .= '<div class="description">' . $element['#description'] . "</div>\n";
+      }
       $output .= ' ' . $prefix . $element['#children'] . $suffix . "\n";
       break;
 
     case 'after':
+      if (!empty($element['#description']) && $element['#description_display'] == 'before') {
+        $output .= '<div class="description">' . $element['#description'] . "</div>\n";
+      }
       $output .= ' ' . $prefix . $element['#children'] . $suffix;
       $output .= ' ' . theme('form_element_label', $variables) . "\n";
       break;
@@ -3926,7 +3943,7 @@ function theme_form_element($variables) {
       break;
   }
 
-  if (!empty($element['#description'])) {
+  if (!empty($element['#description']) && $element['#description_display'] == 'after') {
     $output .= '<div class="description">' . $element['#description'] . "</div>\n";
   }
 
diff --git a/core/modules/simpletest/tests/form.test b/core/modules/simpletest/tests/form.test
index 70ebf86..a58d57b 100644
--- a/core/modules/simpletest/tests/form.test
+++ b/core/modules/simpletest/tests/form.test
@@ -653,6 +653,12 @@ class FormsElementsLabelsTestCase extends DrupalWebTestCase {
 
     $elements = $this->xpath('//div[@id="form-test-textfield-title-suffix"]/preceding-sibling::div[contains(@class, \'form-item-form-textfield-test-title\')]');
     $this->assertTrue(isset($elements[0]), t("Properly places the #suffix element before the form item."));
+
+    $elements = $this->xpath('//div[@class="description"]/preceding-sibling::input[@id="edit-form-textfield-description-after"]');
+    $this->assertTrue(isset($elements[0]), t("Properly places the #description element after the form item."));
+  
+    $elements = $this->xpath('//input[@id="edit-form-textfield-description-before"]/preceding-sibling::div[@class="description"]');
+    $this->assertTrue(isset($elements[0]), t("Properly places the #description element before the form item."));
   }
 }
 
diff --git a/core/modules/simpletest/tests/form_test.module b/core/modules/simpletest/tests/form_test.module
index 0393b18..5f0d9b2 100644
--- a/core/modules/simpletest/tests/form_test.module
+++ b/core/modules/simpletest/tests/form_test.module
@@ -755,6 +755,20 @@ function form_label_test_form() {
     '#type' => 'textfield',
   );
 
+  $form['form_textfield_test_description_before'] = array(
+    '#type' =>'textfield',
+    '#title' => t('Textfield test for description before element'),
+    '#description' => t('Textfield test for description before element'),
+    '#description_display' => 'before'
+  );
+
+  $form['form_textfield_test_description_after'] = array(
+    '#type' =>'textfield',
+    '#title' => t('Textfield test for description after element'),
+    '#description' => t('Textfield test for description after element'),
+    '#description_display' => 'after'
+  );
+ 
   return $form;
 }
 
diff --git a/core/modules/system/system.api.php b/core/modules/system/system.api.php
index 0684f26..5a6469d 100644
--- a/core/modules/system/system.api.php
+++ b/core/modules/system/system.api.php
@@ -226,6 +226,8 @@ function hook_cron_queue_info_alter(&$queues) {
  *  - "#submit": array of callback functions taking $form and $form_state.
  *  - "#title_display": optional string indicating if and how #title should be
  *    displayed, see theme_form_element() and theme_form_element_label().
+ *  - "#description_display": optional string indicating how the #description should
+ *    be displayed, see theme_form_element().
  *
  * @see hook_element_info_alter()
  * @see system_element_info()
