diff --git a/core/core.libraries.yml b/core/core.libraries.yml
index 9cfd1cf..688df07 100644
--- a/core/core.libraries.yml
+++ b/core/core.libraries.yml
@@ -242,6 +242,15 @@ drupal.progress:
     - core/jquery
     - core/drupalSettings
 
+drupal.revealpass:
+  version: VERSION
+  js:
+    misc/revealpass.js: {}
+  dependencies:
+    - core/drupal
+    - core/jquery
+    - core/jquery.once
+
 drupal.states:
   version: VERSION
   js:
diff --git a/core/lib/Drupal/Core/Render/Element/PasswordConfirm.php b/core/lib/Drupal/Core/Render/Element/PasswordConfirm.php
index 0d5e0e2..01e21a5 100644
--- a/core/lib/Drupal/Core/Render/Element/PasswordConfirm.php
+++ b/core/lib/Drupal/Core/Render/Element/PasswordConfirm.php
@@ -81,7 +81,10 @@ public static function processPasswordConfirm(&$element, FormStateInterface $for
       '#title' => t('Confirm password'),
       '#value' => empty($element['#value']) ? NULL : $element['#value']['pass2'],
       '#required' => $element['#required'],
-      '#attributes' => array('class' => array('password-confirm', 'js-password-confirm')),
+      '#attributes' => array(
+        'class' => array('password-confirm', 'js-password-confirm'),
+        'data-drupal-password-strength' => TRUE,
+      ),
       '#error_no_message' => TRUE,
     );
     $element['#element_validate'] = array(array(get_called_class(), 'validatePasswordConfirm'));
diff --git a/core/lib/Drupal/Core/Render/Element/PasswordReveal.php b/core/lib/Drupal/Core/Render/Element/PasswordReveal.php
new file mode 100644
index 0000000..989df2b
--- /dev/null
+++ b/core/lib/Drupal/Core/Render/Element/PasswordReveal.php
@@ -0,0 +1,50 @@
+<?php
+
+namespace Drupal\Core\Render\Element;
+
+use Drupal\Core\Form\FormStateInterface;
+
+/**
+ * Provides a form element for entering a password.
+ *
+ * Password form element has hidden text that may be revealed by the user.
+ *
+ * Usage example:
+ * @code
+ * $form['pass'] = array(
+ *   '#type' => 'password_reveal',
+ *   '#title' => t('Password'),
+ *   '#size' => 25,
+ * );
+ * @endcode
+ *
+ * @see \Drupal\Core\Render\Element\Password
+ *
+ * @FormElement("password_reveal")
+ */
+class PasswordReveal extends Password {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getInfo() {
+    $info = parent::getInfo();
+    $info['#process'][] = [static::class, 'processPasswordReveal'];
+
+    return $info;
+  }
+
+  /**
+   * Adds the attributes needed to add password strength and the reveal button.
+   */
+  public static function processPasswordReveal(&$element, FormStateInterface $form_state, &$complete_form) {
+    $element['#attached']['library'][] = 'core/drupal.revealpass';
+    $element['#attributes']['class'][] = 'password-field';
+    $element['#attributes']['class'][] = 'js-password-field';
+    $element['#attributes']['data-drupal-revealpass'] = TRUE;
+    $element['#attributes']['data-drupal-password-strength'] = TRUE;
+
+    return $element;
+  }
+
+}
diff --git a/core/misc/revealpass.js b/core/misc/revealpass.js
new file mode 100644
index 0000000..7d9a27c
--- /dev/null
+++ b/core/misc/revealpass.js
@@ -0,0 +1,59 @@
+/**
+ * @file
+ * Creates a reveal password link on password inputs.
+ */
+
+(function ($, Drupal) {
+
+  'use strict';
+
+  var showPass = Drupal.t('Show password');
+  var hidePass = Drupal.t('Hide password');
+
+  /**
+   * Reveal click handle that either shows or hides the password.
+   *
+   * @param {jQuery.Event} event
+   *   The jQuery event.
+   */
+  function revealClickHandle(event) {
+    var $pass = $(event.data.password);
+    var $button = $(event.target);
+
+    if ($pass.attr('type') === 'password') {
+      $pass.attr('type', 'text');
+      $button.text(hidePass);
+    }
+    else {
+      $pass.attr('type', 'password');
+      $button.text(showPass);
+    }
+  }
+
+  /**
+   * Create reveal button and bind event.
+   *
+   * @param {number} index
+   * @param {HTMLElement} element
+   */
+  function revealLink(index, element) {
+    var $trigger = $('<button type="button" class="link toggle-password">' + showPass + '</button>');
+
+    $trigger.on('click', {password: element}, revealClickHandle);
+    $trigger.insertAfter(element);
+  }
+
+  /**
+   * Initialize reveal links.
+   *
+   * @type {Drupal~behavior}
+   */
+  Drupal.behaviors.revealPass = {
+    attach: function (context) {
+      $(context).find('input[type=password][data-drupal-revealpass]')
+        .once('revealpass')
+        .each(revealLink);
+    }
+  };
+
+})(jQuery, Drupal);
diff --git a/core/modules/system/tests/modules/form_test/form_test.routing.yml b/core/modules/system/tests/modules/form_test/form_test.routing.yml
index 2250a0b..7572ed5 100644
--- a/core/modules/system/tests/modules/form_test/form_test.routing.yml
+++ b/core/modules/system/tests/modules/form_test/form_test.routing.yml
@@ -489,3 +489,10 @@ form_test.get_form:
     _form: '\Drupal\form_test\Form\FormTestGetForm'
   requirements:
     _access: 'TRUE'
+
+form_test.password_reveal:
+  path: '/form-test/password-reveal'
+  defaults:
+    _form: '\Drupal\form_test\Form\FormTestPasswordReveal'
+  requirements:
+    _access: 'TRUE'
diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestPasswordReveal.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestPasswordReveal.php
new file mode 100644
index 0000000..19bf800
--- /dev/null
+++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestPasswordReveal.php
@@ -0,0 +1,43 @@
+<?php
+
+namespace Drupal\form_test\Form;
+
+use Drupal\Core\Form\FormBase;
+use Drupal\Core\Form\FormStateInterface;
+
+/**
+ * Form constructor for testing #type 'url' elements.
+ */
+class FormTestPasswordReveal extends FormBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormId() {
+    return 'form_test_password_reveal';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildForm(array $form, FormStateInterface $form_state) {
+    $form['password_one'] = array(
+      '#title' => $this->t('Password One'),
+      '#type' => 'password_reveal',
+      '#size' => 25,
+    );
+    $form['password_two'] = array(
+      '#title' => $this->t('Password Two'),
+      '#type' => 'password_reveal',
+      '#size' => 25,
+    );
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, FormStateInterface $form_state) {
+  }
+
+}
diff --git a/core/modules/user/config/install/user.settings.yml b/core/modules/user/config/install/user.settings.yml
index 8372ccd..7e12609 100644
--- a/core/modules/user/config/install/user.settings.yml
+++ b/core/modules/user/config/install/user.settings.yml
@@ -13,4 +13,5 @@ register: visitors
 cancel_method: user_cancel_block
 password_reset_timeout: 86400
 password_strength: true
+password_type_reveal: false
 langcode: en
diff --git a/core/modules/user/config/schema/user.schema.yml b/core/modules/user/config/schema/user.schema.yml
index 627d8a6..81f224b 100644
--- a/core/modules/user/config/schema/user.schema.yml
+++ b/core/modules/user/config/schema/user.schema.yml
@@ -50,6 +50,9 @@ user.settings:
     password_strength:
       type: boolean
       label: 'Enable password strength indicator'
+    password_type_reveal:
+      type: boolean
+      label: 'Use password reveal on account edit page'
 
 user.mail:
  type: config_object
diff --git a/core/modules/user/src/AccountForm.php b/core/modules/user/src/AccountForm.php
index 05257fd..494d274 100644
--- a/core/modules/user/src/AccountForm.php
+++ b/core/modules/user/src/AccountForm.php
@@ -121,11 +121,21 @@ public function form(array $form, FormStateInterface $form_state) {
     // Display password field only for existing users or when user is allowed to
     // assign a password during registration.
     if (!$register) {
-      $form['account']['pass'] = array(
-        '#type' => 'password_confirm',
-        '#size' => 25,
-        '#description' => $this->t('To change the current user password, enter the new password in both fields.'),
-      );
+      if ($config->get('password_type_reveal')) {
+        $form['account']['pass'] = array(
+          '#title' => $this->t('Password'),
+          '#type' => 'password_reveal',
+          '#size' => 25,
+          '#description' => $this->t('To change the current user password, enter the new password.'),
+        );
+      }
+      else {
+        $form['account']['pass'] = array(
+          '#type' => 'password_confirm',
+          '#size' => 25,
+          '#description' => $this->t('To change the current user password, enter the new password in both fields.'),
+        );
+      }
 
       // To skip the current password field, the user must have logged in via a
       // one-time link and have the token in the URL. Store this in $form_state
@@ -163,12 +173,23 @@ public function form(array $form, FormStateInterface $form_state) {
       }
     }
     elseif (!$config->get('verify_mail') || $admin) {
-      $form['account']['pass'] = array(
-        '#type' => 'password_confirm',
-        '#size' => 25,
-        '#description' => $this->t('Provide a password for the new account in both fields.'),
-        '#required' => TRUE,
-      );
+      if ($config->get('password_type_reveal')) {
+        $form['account']['pass'] = array(
+          '#title' => $this->t('Password'),
+          '#type' => 'password_reveal',
+          '#size' => 25,
+          '#description' => $this->t('Provide a password for the new account.'),
+          '#required' => TRUE,
+        );
+      }
+      else {
+        $form['account']['pass'] = array(
+          '#type' => 'password_confirm',
+          '#size' => 25,
+          '#description' => $this->t('Provide a password for the new account in both fields.'),
+          '#required' => TRUE,
+        );
+      }
     }
 
     // When not building the user registration form, prevent web browsers from
diff --git a/core/modules/user/src/AccountSettingsForm.php b/core/modules/user/src/AccountSettingsForm.php
index 1e5cd49..07b71db 100644
--- a/core/modules/user/src/AccountSettingsForm.php
+++ b/core/modules/user/src/AccountSettingsForm.php
@@ -165,6 +165,11 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       '#title' => $this->t('Enable password strength indicator'),
       '#default_value' => $config->get('password_strength'),
     );
+    $form['registration_cancellation']['user_password_type_reveal'] = array(
+      '#type' => 'checkbox',
+      '#title' => $this->t('Use password reveal, not password confirm, on account edit pages'),
+      '#default_value' => $config->get('password_type_reveal'),
+    );
     $form['registration_cancellation']['user_cancel_method'] = array(
       '#type' => 'radios',
       '#title' => $this->t('When cancelling a user account'),
@@ -429,6 +434,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
       ->set('anonymous', $form_state->getValue('anonymous'))
       ->set('register', $form_state->getValue('user_register'))
       ->set('password_strength', $form_state->getValue('user_password_strength'))
+      ->set('password_type_reveal', $form_state->getValue('user_password_type_reveal'))
       ->set('verify_mail', $form_state->getValue('user_email_verification'))
       ->set('cancel_method', $form_state->getValue('user_cancel_method'))
       ->set('notify.status_activated', $form_state->getValue('user_mail_status_activated_notify'))
diff --git a/core/modules/user/src/Tests/UserEditTest.php b/core/modules/user/src/Tests/UserEditTest.php
index 5b34d2e..f566677 100644
--- a/core/modules/user/src/Tests/UserEditTest.php
+++ b/core/modules/user/src/Tests/UserEditTest.php
@@ -108,6 +108,19 @@ function testUserEdit() {
     $this->assertText(t('The changes have been saved.'));
     $this->assertNoFieldChecked('edit-status-0');
     $this->assertFieldChecked('edit-status-1');
+
+    // Test editing the user with a password_reveal field.
+    $config->set('password_type_reveal', TRUE)->save();
+    $config->set('password_strength', TRUE)->save();
+
+    $this->drupalGet("user/" . $admin_user->id() . "/edit");
+    $this->assertRaw('Password strength:', 'The password strength indicator is displayed.');
+
+    $edit = array();
+    $edit['pass'] = $this->randomMachineName();
+    $edit['current_pass'] = $admin_user->pass_raw;
+    $this->drupalPostForm("user/" . $admin_user->id() . "/edit", $edit, t('Save'));
+    $this->assertRaw(t("The changes have been saved."));
   }
 
   /**
diff --git a/core/modules/user/user.install b/core/modules/user/user.install
index 7cc46ef..6cb2b7c 100644
--- a/core/modules/user/user.install
+++ b/core/modules/user/user.install
@@ -105,5 +105,12 @@ function user_update_8100() {
 }
 
 /**
+ * Add the configuration setting for password_type_reveal.
+ */
+function user_update_8101() {
+  \Drupal::configFactory()->getEditable('user.settings')->set('password_type_reveal', FALSE)->save();
+}
+
+/**
  * @} End of "addtogroup updates-8.1.0-beta".
  */
diff --git a/core/modules/user/user.js b/core/modules/user/user.js
index f4602c6..582848b 100644
--- a/core/modules/user/user.js
+++ b/core/modules/user/user.js
@@ -37,7 +37,6 @@
           .parent()
           .append('<div aria-live="polite" aria-atomic="true" class="password-confirm js-password-confirm">' + translate.confirmTitle + ' <span></span></div>')
           .addClass('confirm-parent');
-
         var $confirmInput = $passwordInputParentWrapper.find('input.js-password-confirm');
         var $confirmResult = $passwordInputParentWrapper.find('div.js-password-confirm');
         var $confirmChild = $confirmResult.find('span');
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index 90b813f..598ff25 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -1228,6 +1228,9 @@ function user_element_info_alter(array &$types) {
   if (isset($types['password_confirm'])) {
     $types['password_confirm']['#process'][] = 'user_form_process_password_confirm';
   }
+  if (isset($types['password_reveal'])) {
+    $types['password_reveal']['#process'][] = 'user_form_process_password_reveal';
+  }
 }
 
 /**
@@ -1271,6 +1274,44 @@ function user_form_process_password_confirm($element) {
 }
 
 /**
+ * Form element process handler for client-side password validation.
+ *
+ * This #process handler is automatically invoked for 'password_reveal' form
+ * elements to add the JavaScript to display and hide the password and string
+ * translations for dynamic password validation.
+ */
+function user_form_process_password_reveal($element) {
+  $password_settings = array(
+    'confirmTitle' => '',
+    'showStrengthIndicator' => FALSE,
+  );
+
+  if (\Drupal::config('user.settings')->get('password_strength')) {
+    $password_settings['showStrengthIndicator'] = TRUE;
+    $password_settings += array(
+      'strengthTitle' => t('Password strength:'),
+      'hasWeaknesses' => t('To make your password stronger:'),
+      'tooShort' => t('Make it at least 12 characters'),
+      'addLowerCase' => t('Add lowercase letters'),
+      'addUpperCase' => t('Add uppercase letters'),
+      'addNumbers' => t('Add numbers'),
+      'addPunctuation' => t('Add punctuation'),
+      'sameAsUsername' => t('Make it different from your username'),
+      'weak' => t('Weak'),
+      'fair' => t('Fair'),
+      'good' => t('Good'),
+      'strong' => t('Strong'),
+      'username' => \Drupal::currentUser()->getUsername(),
+    );
+  }
+
+  $element['#attached']['library'][] = 'user/drupal.user';
+  $element['#attached']['drupalSettings']['password'] = $password_settings;
+
+  return $element;
+}
+
+/**
  * Implements hook_modules_uninstalled().
  */
 function user_modules_uninstalled($modules) {
diff --git a/core/tests/Drupal/FunctionalJavascriptTests/Core/Form/PasswordRevealTest.php b/core/tests/Drupal/FunctionalJavascriptTests/Core/Form/PasswordRevealTest.php
new file mode 100644
index 0000000..3c4cd06
--- /dev/null
+++ b/core/tests/Drupal/FunctionalJavascriptTests/Core/Form/PasswordRevealTest.php
@@ -0,0 +1,54 @@
+<?php
+
+namespace Drupal\FunctionalJavascriptTests\Core\Form;
+
+use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
+
+/**
+ * Tests the state of elements based on another elements.
+ *
+ * @group javascript
+ */
+class PasswordRevealTest extends JavascriptTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['form_test'];
+
+  /**
+   * Test the password_reveal form element functionality.
+   */
+  public function testPasswordRevealFormElement() {
+    $this->drupalGet('/form-test/password-reveal');
+    $page = $this->getSession()->getPage();
+
+    $toogle_password_one_link = $page->find('css', '.toggle-password');
+    $password_one_field = $page->findById('edit-password-one');
+    $password_two_field = $page->findById('edit-password-two');
+
+    /* Initial state: before the show password link is clicked. */
+
+    // Test that both password fields type is password.
+    $this->assertEquals($password_one_field->getAttribute('type'), 'password');
+    $this->assertEquals($password_two_field->getAttribute('type'), 'password');
+
+    // Change state: click the "show password" of password one link.
+    $toogle_password_one_link->click();
+
+    // Test that the password one field type is now text.
+    $this->assertEquals($password_one_field->getAttribute('type'), 'text');
+    // Test that the password two field type is still password.
+    $this->assertEquals($password_two_field->getAttribute('type'), 'password');
+
+    // Change state: click the "hide password" link.
+    $toogle_password_one_link->click();
+
+    // Test that the password field type is password.
+    $this->assertEquals($password_one_field->getAttribute('type'), 'password');
+    // Test that the password two field type is still password.
+    $this->assertEquals($password_two_field->getAttribute('type'), 'password');
+
+  }
+
+}
diff --git a/core/tests/Drupal/Tests/Core/Render/Element/PasswordRevealTest.php b/core/tests/Drupal/Tests/Core/Render/Element/PasswordRevealTest.php
new file mode 100644
index 0000000..9fbffdb
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Render/Element/PasswordRevealTest.php
@@ -0,0 +1,45 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\Core\Render\Element\PasswordRevealTest.
+ */
+
+namespace Drupal\Tests\Core\Render\Element;
+
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Render\Element\PasswordReveal;
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * @coversDefaultClass \Drupal\Core\Render\Element\PasswordReveal
+ * @group Render
+ */
+class PasswordRevealTest extends UnitTestCase {
+
+  /**
+   * @covers ::valueCallback
+   *
+   * @dataProvider providerTestValueCallback
+   */
+  public function testValueCallback($expected, $input) {
+    $element = [];
+    $form_state = $this->prophesize(FormStateInterface::class)->reveal();
+    $this->assertSame($expected, PasswordReveal::valueCallback($element, $input, $form_state));
+  }
+
+  /**
+   * Data provider for testValueCallback().
+   */
+  public function providerTestValueCallback() {
+    $data = [];
+    $data[] = [NULL, FALSE];
+    $data[] = [NULL, NULL];
+    $data[] = ['', ['test']];
+    $data[] = ['test', 'test'];
+    $data[] = ['123', 123];
+
+    return $data;
+  }
+
+}
diff --git a/core/themes/classy/css/components/user.css b/core/themes/classy/css/components/user.css
index d62ff25..5905e85 100644
--- a/core/themes/classy/css/components/user.css
+++ b/core/themes/classy/css/components/user.css
@@ -54,6 +54,11 @@
 [dir="rtl"] .password-parent {
   clear: right;
 }
+@media all and (min-width: 600px) {
+  .password-parent .toggle-password {
+    margin: 0 0.75em;
+  }
+}
 
 /* Styling for the status indicator of the passwords match test.  */
 .password-confirm .ok {
