diff --git a/core/modules/user/lib/Drupal/user/Form/UserPasswordForm.php b/core/modules/user/lib/Drupal/user/Form/UserPasswordForm.php
index 236b293..58676c4 100644
--- a/core/modules/user/lib/Drupal/user/Form/UserPasswordForm.php
+++ b/core/modules/user/lib/Drupal/user/Form/UserPasswordForm.php
@@ -7,6 +7,8 @@
 
 namespace Drupal\user\Form;
 
+use Drupal\Core\Config\ConfigFactory;
+use Drupal\Core\Flood\FloodInterface;
 use Drupal\Core\Field\Plugin\Field\FieldType\EmailItem;
 use Drupal\Core\Form\FormBase;
 use Drupal\Core\Language\Language;
@@ -28,6 +30,20 @@ class UserPasswordForm extends FormBase {
   protected $userStorageController;
 
   /**
+   * The flood service.
+   *
+   * @var \Drupal\Core\Flood\FloodInterface
+   */
+  protected $flood;
+
+  /**
+   * The config factory.
+   *
+   * @var \Drupal\Core\Config\ConfigFactory
+   */
+  protected $configFactory;
+
+  /**
    * The language manager.
    *
    * @var \Drupal\Core\Language\LanguageManager
@@ -41,10 +57,16 @@ class UserPasswordForm extends FormBase {
    *   The user storage controller.
    * @param \Drupal\Core\Language\LanguageManager $language_manager
    *   The language manager.
+   * @param \Drupal\Core\Config\ConfigFactory $config_factory
+   *   The config factory.
+   * @param \Drupal\Core\Flood\FloodInterface $flood
+   *   The flood service.
    */
-  public function __construct(UserStorageControllerInterface $user_storage_controller, LanguageManager $language_manager) {
+  public function __construct(UserStorageControllerInterface $user_storage_controller, LanguageManager $language_manager, ConfigFactory $config_factory, FloodInterface $flood) {
     $this->userStorageController = $user_storage_controller;
     $this->languageManager = $language_manager;
+    $this->configFactory = $config_factory;
+    $this->flood = $flood;
   }
 
   /**
@@ -53,7 +75,9 @@ public function __construct(UserStorageControllerInterface $user_storage_control
   public static function create(ContainerInterface $container) {
     return new static(
       $container->get('entity.manager')->getStorageController('user'),
-      $container->get('language_manager')
+      $container->get('language_manager'),
+      $container->get('config.factory'),
+      $container->get('flood')
     );
   }
 
@@ -108,19 +132,26 @@ public function buildForm(array $form, array &$form_state) {
    * {@inheritdoc}
    */
   public function validateForm(array &$form, array &$form_state) {
-    $name = trim($form_state['values']['name']);
-    // Try to load by email.
-    $users = $this->userStorageController->loadByProperties(array('mail' => $name, 'status' => '1'));
-    if (empty($users)) {
-      // No success, try to load by name.
-      $users = $this->userStorageController->loadByProperties(array('name' => $name, 'status' => '1'));
-    }
-    $account = reset($users);
-    if ($account && $account->id()) {
-      form_set_value(array('#parents' => array('account')), $account, $form_state);
+    $flood_config = $this->configFactory->get('user.flood');
+    if ($this->flood->isAllowed('user.password_request', $flood_config->get('ip_limit'), $flood_config->get('ip_window'))) {
+      $this->flood->register('user.password_request', $flood_config->get('ip_window'));
+      $name = trim($form_state['values']['name']);
+      // Try to load by email.
+      $users = $this->userStorageController->loadByProperties(array('mail' => $name, 'status' => '1'));
+      if (empty($users)) {
+        // No success, try to load by name.
+        $users = $this->userStorageController->loadByProperties(array('name' => $name, 'status' => '1'));
+      }
+      $account = reset($users);
+      if ($account && $account->id()) {
+        \Drupal::formBuilder()->setValue(array('#parents' => array('account')), $account, $form_state);
+      }
+      else {
+        $this->setFormError('name', $form_state, $this->t('Sorry, %name is not recognized as a username or an e-mail address.', array('%name' => $name)));
+      }
     }
     else {
-      $this->setFormError('name', $form_state, $this->t('Sorry, %name is not recognized as a username or an e-mail address.', array('%name' => $name)));
+      $this->setFormError('name', $form_state, $this->t('Reset password limit exceeded.  Please contact technical support for further assistance.'));
     }
   }
 
diff --git a/core/modules/user/lib/Drupal/user/Tests/UserPasswordResetTest.php b/core/modules/user/lib/Drupal/user/Tests/UserPasswordResetTest.php
index f8635fd..0367e2e 100644
--- a/core/modules/user/lib/Drupal/user/Tests/UserPasswordResetTest.php
+++ b/core/modules/user/lib/Drupal/user/Tests/UserPasswordResetTest.php
@@ -54,22 +54,10 @@ public function setUp() {
    */
   function testUserPasswordReset() {
     // Try to reset the password for an invalid account.
-    $this->drupalGet('user/password');
-
-    $edit = array('name' => $this->randomName(32));
-    $this->drupalPostForm(NULL, $edit, t('E-mail new password'));
-
-    $this->assertText(t('Sorry, @name is not recognized as a username or an e-mail address.', array('@name' => $edit['name'])), 'Validation error message shown when trying to request password for invalid account.');
-    $this->assertEqual(count($this->drupalGetMails(array('id' => 'user_password_reset'))), 0, 'No e-mail was sent when requesting a password for an invalid account.');
+    $this->assertPasswordReset($this->randomName(32), FALSE);
 
     // Reset the password by username via the password reset page.
-    $edit['name'] = $this->account->getUsername();
-    $this->drupalPostForm(NULL, $edit, t('E-mail new password'));
-
-     // Verify that the user was sent an e-mail.
-    $this->assertMail('to', $this->account->getEmail(), 'Password e-mail sent to user.');
-    $subject = t('Replacement login information for @username at @site', array('@username' => $this->account->getUsername(), '@site' => \Drupal::config('system.site')->get('name')));
-    $this->assertMail('subject', $subject, 'Password reset e-mail subject is correct.');
+    $this->assertPasswordReset($this->account->getUsername(), TRUE);
 
     $resetURL = $this->getResetURL();
     $this->drupalGet($resetURL);
@@ -89,11 +77,9 @@ function testUserPasswordReset() {
     $this->assertText(t('You have tried to use a one-time login link that has either been used or is no longer valid. Please request a new one using the form below.'), 'One-time link is no longer valid.');
 
     // Request a new password again, this time using the e-mail address.
-    $this->drupalGet('user/password');
     // Count email messages before to compare with after.
     $before = count($this->drupalGetMails(array('id' => 'user_password_reset')));
-    $edit['name'] = $this->account->getEmail();
-    $this->drupalPostForm(NULL, $edit, t('E-mail new password'));
+    $this->assertPasswordReset($this->account->getEmail(), TRUE);
     $this->assertTrue( count($this->drupalGetMails(array('id' => 'user_password_reset'))) === $before + 1, 'E-mail sent when requesting password reset using e-mail address.');
 
     // Create a password reset link as if the request time was 60 seconds older than the allowed limit.
@@ -133,4 +119,61 @@ public function testUserResetPasswordTextboxFilled() {
     $this->drupalGet('user/password', array('query' => array('name' => $edit['name'])));
     $this->assertFieldByName('name', $edit['name'], 'User name found.');
   }
+
+  /**
+   * Test password reset flood control.
+   */
+  public function testUserResetPasswordFloodControl() {
+    \Drupal::config('user.flood')
+      ->set('ip_limit', 5)
+      ->save();
+
+    // Try 5 requests that should not trigger flood control.
+    for ($i = 0; $i < 5; $i++) {
+      $this->assertPasswordReset($this->account->getUsername(), TRUE);
+    }
+
+    // The next request should trigger flood control.
+    $this->assertPasswordReset($this->account->getUsername(), TRUE, TRUE);
+  }
+
+  /**
+   * Make a password request.
+   *
+   * This test checks both that the correct messaging is shown and that
+   * e-mail notifications are sent to the user in case of successful request.
+   *
+   * @param $name
+   *   The user name or email address to use for the request.
+   * @param $valid_trigger
+   *   Whether of not to expect the $name is valid.
+   * @param $flood_trigger
+   *   Whether or not to expect that the flood control mechanism will be
+   *   triggered.
+   */
+  public function assertPasswordReset($name, $valid_trigger = TRUE, $flood_trigger = NULL) {
+    $this->drupalGet('user/password');
+
+    $edit = array('name' => $name);
+    $this->drupalPostForm(NULL, $edit, t('E-mail new password'));
+
+    if (isset($flood_trigger)) {
+      $this->assertText(t('Reset password limit exceeded.  Please contact technical support for further assistance.'), 'Flood error message shown.');
+    }
+    else {
+      if ($valid_trigger) {
+        // Make sure the error text is not displayed and email sent.
+        $this->assertNoText(t('Sorry, @name is not recognized as a username or an e-mail address.', array('@name' => $edit['name'])), 'Validation error message shown when trying to request password for invalid account.');
+        $this->assertMail('to', $this->account->getEmail(), 'Password e-mail sent to user.');
+        $subject = t('Replacement login information for @username at @site', array('@username' => $this->account->getUsername(), '@site' => \Drupal::config('system.site')->get('name')));
+        $this->assertMail('subject', $subject, 'Password reset e-mail subject is correct.');
+
+      }
+      else {
+        // Make sure the error text is displayed and no email sent.
+        $this->assertText(t('Sorry, @name is not recognized as a username or an e-mail address.', array('@name' => $edit['name'])), 'Validation error message shown when trying to request password for invalid account.');
+        $this->assertEqual(count($this->drupalGetMails(array('id' => 'user_password_reset'))), 0, 'No e-mail was sent when requesting a password for an invalid account.');
+      }
+    }
+  }
 }
