diff --git a/core/includes/form.inc b/core/includes/form.inc
index 665a9e6..6b02b15 100644
--- a/core/includes/form.inc
+++ b/core/includes/form.inc
@@ -3959,6 +3959,23 @@ function form_validate_url(&$element, &$form_state) {
   }
 }
 
+/*
+ * Returns TRUE if the form has any fields required.
+ *
+ * @param $form
+ *   The form to be checked for required fields.
+ */
+function drupal_form_has_required ($form) {
+  if (isset($form['#required']) && $form['#required']) {
+    return TRUE;
+  }
+  foreach (element_children($form) as $key) {
+    if (drupal_form_has_required($form[$key])) {
+      return TRUE;
+    }
+  }
+}
+
 /**
  * Returns HTML for a form.
  *
@@ -3970,6 +3987,12 @@ function form_validate_url(&$element, &$form_state) {
  * @ingroup themeable
  */
 function theme_form($variables) {
+  $has_required = drupal_form_has_required($variables['element']);
+  if ($has_required) {
+    // This is also used in the installer, pre-database setup.
+    $t = get_t();
+    $form_prefix = '<div class="form-required-info"><span class="form-required">*</span>'. $t(' indicates required fields') .'</div>';
+  }
   $element = $variables['element'];
   if (isset($element['#action'])) {
     $element['#attributes']['action'] = drupal_strip_dangerous_protocols($element['#action']);
@@ -3979,7 +4002,12 @@ function theme_form($variables) {
     $element['#attributes']['accept-charset'] = "UTF-8";
   }
   // Anonymous DIV to satisfy XHTML compliance.
-  return '<form' . drupal_attributes($element['#attributes']) . '><div>' . $element['#children'] . '</div></form>';
+  if($has_required) {
+    return '<form' . drupal_attributes($element['#attributes']) . '>'. $form_prefix .'<div>' . $element['#children'] . '</div></form>';
+  }
+  else {
+    return '<form' . drupal_attributes($element['#attributes']) . '><div>' . $element['#children'] . '</div></form>';
+  }
 }
 
 /**
