diff --git a/includes/common.inc b/includes/common.inc
index ce08390..af08f42 100644
--- a/includes/common.inc
+++ b/includes/common.inc
@@ -1734,7 +1734,8 @@ function format_plural($count, $singular, $plural, array $args = array(), array
 
   // Get the plural index through the gettext formula.
   $index = (function_exists('locale_get_plural')) ? locale_get_plural($count, isset($options['langcode']) ? $options['langcode'] : NULL) : -1;
-  // Backwards compatibility.
+  // If the index cannot be computed, use the plural as a fallback (which
+  // allows for most flexiblity with the replaceable @count value).
   if ($index < 0) {
     return t($plural, $args, $options);
   }
diff --git a/modules/locale/locale.module b/modules/locale/locale.module
index 43c5e13..5be6720 100644
--- a/modules/locale/locale.module
+++ b/modules/locale/locale.module
@@ -737,30 +737,51 @@ function locale_reset() {
  * @param $langcode
  *   Optional language code to translate to a language other than
  *   what is used to display the page.
+ *
+ * @return
+ *   The numeric index of the plural variant to use for this $langcode and
+ *   $count combination or -1 if the language was not found or does not have a
+ *   plural formula.
  */
 function locale_get_plural($count, $langcode = NULL) {
   global $language;
-  $locale_formula = &drupal_static(__FUNCTION__, array());
-  $plurals = &drupal_static(__FUNCTION__ . ':plurals', array());
+
+  // Used to locally cache the plural formulas for all languages.
+  $plural_formulas = &drupal_static(__FUNCTION__, array());
+
+  // Used to store precomputed plural indexes corresponding to numbers
+  // individually for each language.
+  $plural_indexes = &drupal_static(__FUNCTION__ . ':plurals', array());
 
   $langcode = $langcode ? $langcode : $language->language;
 
-  if (!isset($plurals[$langcode][$count])) {
-    if (empty($locale_formula)) {
+  if (!isset($plural_indexes[$langcode][$count])) {
+    // Retrieve and statically cache the plural formulas for all languages.
+    if (empty($plural_formulas)) {
       $language_list = language_list();
-      $locale_formula[$langcode] = $language_list[$langcode]->formula;
+      foreach ($language_list as $langcode => $lang) {
+        $plural_formulas[$langcode] = $lang->formula;
+      }
     }
-    if ($locale_formula[$langcode]) {
+    // If there is a plural formula for the language, evaluate it for the given
+    // $count and statically cache the result for the combination of language
+    // and count, since the result will always be identical.
+    if (!empty($plural_formulas[$langcode])) {
+      // $n is used inside the expression in the eval().
       $n = $count;
-      $plurals[$langcode][$count] = @eval('return intval(' . $locale_formula[$langcode] . ');');
-      return $plurals[$langcode][$count];
+      $plural_indexes[$langcode][$count] = @eval('return intval(' . $plural_formulas[$langcode] . ');');
+    }
+    // In case there is no plural formula for English (no imported translation
+    // for English), use a default formula.
+    elseif ($langcode == 'en') {
+      $plural_indexes[$langcode][$count] = (int) ($count != 1);
     }
+    // Otherwise, return -1 (unknown).
     else {
-      $plurals[$langcode][$count] = -1;
-      return -1;
+      $plural_indexes[$langcode][$count] = -1;
     }
   }
-  return $plurals[$langcode][$count];
+  return $plural_indexes[$langcode][$count];
 }
 
 
diff --git a/modules/locale/locale.test b/modules/locale/locale.test
index c922c1d..0a8ed42 100644
--- a/modules/locale/locale.test
+++ b/modules/locale/locale.test
@@ -694,6 +694,136 @@ class LocaleTranslationFunctionalTest extends DrupalWebTestCase {
 }
 
 /**
+ * Tests plural index computation functionality.
+ */
+class LocalePluralFormatTest extends DrupalWebTestCase {
+  public static function getInfo() {
+    return array(
+      'name' => 'Plural formula evaluation',
+      'description' => 'Tests plural formula evaluation for various languages.',
+      'group' => 'Locale',
+    );
+  }
+
+  function setUp() {
+    parent::setUp('locale', 'locale_test');
+
+    $admin_user = $this->drupalCreateUser(array('administer languages', 'translate interface', 'access administration pages'));
+    $this->drupalLogin($admin_user);
+
+    // Import some .po files with formulas to set up the environment.
+    // These will also add the languages to the system and enable them.
+    $this->importPoFile($this->getPoFileWithSimplePlural(), array(
+      'langcode' => 'fr',
+    ));
+    $this->importPoFile($this->getPoFileWithComplexPlural(), array(
+      'langcode' => 'hr',
+    ));
+  }
+
+  /**
+   * Tests locale_get_plural() functionality.
+   */
+  function testGetPluralFormat() {
+    $this->drupalGet('locale_test_plural_format_page');
+    $tests = _locale_test_plural_format_tests();
+    $result = array();
+    foreach ($tests as $test) {
+      $this->assertPluralFormat($test['count'], $test['language'], $test['expected-result']);
+    }
+  }
+
+  /**
+   * Helper assert to test locale_get_plural page.
+   *
+   * @param $count
+   *  Number for testing.
+   * @param $lang
+   *  Language for testing
+   * @param $expected_result
+   *   Expected result.
+   * @param $message
+   */
+  function assertPluralFormat($count, $lang, $expected_result) {
+    $message_param =  array(
+      '@lang' => $lang,
+      '@count' => $count,
+      '@expected_result' => $expected_result,
+    );
+    $message = t("Computed plural index for '@lang' with count @count is @expected_result.", $message_param);
+
+    $message_param = array(
+      '@lang' => $lang,
+      '@expected_result' => $expected_result,
+    );
+    $this->assertText(format_string('Language: @lang, locale_get_plural: @expected_result.', $message_param, $message));
+  }
+
+  /**
+   * Imports a standalone .po file in a given language.
+   *
+   * @param $contents
+   *   Contents of the .po file to import.
+   * @param $options
+   *   Additional options to pass to the translation import form.
+   */
+  function importPoFile($contents, array $options = array()) {
+    $name = tempnam('temporary://', "po_") . '.po';
+    file_put_contents($name, $contents);
+    $options['files[file]'] = $name;
+    $this->drupalPost('admin/config/regional/translate/import', $options, t('Import'));
+    drupal_unlink($name);
+  }
+
+  /**
+   * Returns a .po file with a simple plural formula.
+   */
+  function getPoFileWithSimplePlural() {
+    return <<< EOF
+msgid ""
+msgstr ""
+"Project-Id-Version: Drupal 7\\n"
+"MIME-Version: 1.0\\n"
+"Content-Type: text/plain; charset=UTF-8\\n"
+"Content-Transfer-Encoding: 8bit\\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\\n"
+
+msgid "One sheep"
+msgid_plural "@count sheep"
+msgstr[0] "un mouton"
+msgstr[1] "@count moutons"
+
+msgid "Monday"
+msgstr "lundi"
+EOF;
+  }
+
+  /**
+   * Returns a .po file with a complex plural formula.
+   */
+  function getPoFileWithComplexPlural() {
+    return <<< EOF
+msgid ""
+msgstr ""
+"Project-Id-Version: Drupal 7\\n"
+"MIME-Version: 1.0\\n"
+"Content-Type: text/plain; charset=UTF-8\\n"
+"Content-Transfer-Encoding: 8bit\\n"
+"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\\n"
+
+msgid "1 hour"
+msgid_plural "@count hours"
+msgstr[0] "@count sat"
+msgstr[1] "@count sata"
+msgstr[2] "@count sati"
+
+msgid "Monday"
+msgstr "Ponedjeljak"
+EOF;
+  }
+}
+
+/**
  * Functional tests for the import of translation files.
  */
 class LocaleImportFunctionalTest extends DrupalWebTestCase {
@@ -2835,3 +2965,4 @@ class LocaleLanguageNegotiationInfoFunctionalTest extends DrupalWebTestCase {
     }
   }
 }
+
diff --git a/modules/locale/tests/locale_test.module b/modules/locale/tests/locale_test.module
index 2af50a6..64f4aed 100644
--- a/modules/locale/tests/locale_test.module
+++ b/modules/locale/tests/locale_test.module
@@ -55,6 +55,22 @@ function locale_test_language_types_info() {
 }
 
 /**
+ * Implements hook_menu().
+ *
+ * @return array
+ */
+function locale_test_menu() {
+  $items = array();
+  $items['locale_test_plural_format_page'] = array(
+    'page callback' => 'locale_test_plural_format_page',
+    'access callback' => TRUE,
+    'type' => MENU_CALLBACK,
+  );
+
+  return $items;
+}
+
+/**
  * Implements hook_language_types_info_alter().
  */
 function locale_test_language_types_info_alter(array &$language_types) {
@@ -116,3 +132,111 @@ function locale_test_store_language_negotiation() {
 function locale_test_language_provider($languages) {
   return 'it';
 }
+
+/**
+ * Returns markup for locale_get_plural testing.
+ *
+ * @return array
+ */
+function locale_test_plural_format_page() {
+  $tests = _locale_test_plural_format_tests();
+  $result = array();
+  foreach ($tests as $test) {
+    $string_param = array(
+      '@lang' => $test['language'],
+      '@locale_get_plural' => locale_get_plural($test['count'], $test['language'])
+    );
+    $result[] = array(
+      '#prefix' => '<br/>',
+      '#markup' => format_string('Language: @lang, locale_get_plural: @locale_get_plural.', $string_param),
+    );
+  }
+  return $result;
+}
+
+/**
+ * Helper function with list of test cases
+ *
+ * @return array
+ */
+function _locale_test_plural_format_tests() {
+  return array(
+    // Test data for English (no formula present).
+    array(
+      'count' => 1,
+      'language' => 'en',
+      'expected-result' => 0,
+    ),
+    array(
+      'count' => 0,
+      'language' => 'en',
+      'expected-result' => 1,
+    ),
+    array(
+      'count' => 5,
+      'language' => 'en',
+      'expected-result' => 1,
+    ),
+
+    // Test data for French (simpler formula).
+    array(
+      'count' => 1,
+      'language' => 'fr',
+      'expected-result' => 0,
+    ),
+    array(
+      'count' => 0,
+      'language' => 'fr',
+      'expected-result' => 1,
+    ),
+    array(
+      'count' => 5,
+      'language' => 'fr',
+      'expected-result' => 1,
+    ),
+
+    // Test data for Croatian (more complex formula).
+    array(
+      'count' => 1,
+      'language' => 'hr',
+      'expected-result' => 0,
+    ),
+    array(
+      'count' => 21,
+      'language' => 'hr',
+      'expected-result' => 0,
+    ),
+    array(
+      'count' => 0,
+      'language' => 'hr',
+      'expected-result' => 2,
+    ),
+    array(
+      'count' => 2,
+      'language' => 'hr',
+      'expected-result' => 1,
+    ),
+    array(
+      'count' => 8,
+      'language' => 'hr',
+      'expected-result' => 2,
+    ),
+
+    // Test data for Hungarian (nonexistent language).
+    array(
+      'count' => 1,
+      'language' => 'hu',
+      'expected-result' => -1,
+    ),
+    array(
+      'count' => 21,
+      'language' => 'hu',
+      'expected-result' => -1,
+    ),
+    array(
+      'count' => 0,
+      'language' => 'hu',
+      'expected-result' => -1,
+    ),
+  );
+}
