diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/d6/Upgrade6Test.php b/core/modules/migrate_drupal_ui/tests/src/Functional/d6/Upgrade6Test.php
index b6a7e80fda..7c387408ac 100644
--- a/core/modules/migrate_drupal_ui/tests/src/Functional/d6/Upgrade6Test.php
+++ b/core/modules/migrate_drupal_ui/tests/src/Functional/d6/Upgrade6Test.php
@@ -82,7 +82,7 @@ protected function getEntityCounts() {
       'search_page' => 2,
       'shortcut' => 2,
       'shortcut_set' => 1,
-      'action' => 23,
+      'action' => 24,
       'menu' => 8,
       'taxonomy_term' => 15,
       'taxonomy_vocabulary' => 7,
diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/d7/Upgrade7Test.php b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/Upgrade7Test.php
index b1ec8a675c..d66fd61433 100644
--- a/core/modules/migrate_drupal_ui/tests/src/Functional/d7/Upgrade7Test.php
+++ b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/Upgrade7Test.php
@@ -84,7 +84,7 @@ protected function getEntityCounts() {
       'search_page' => 2,
       'shortcut' => 6,
       'shortcut_set' => 2,
-      'action' => 17,
+      'action' => 18,
       'menu' => 6,
       'taxonomy_term' => 24,
       'taxonomy_vocabulary' => 7,
diff --git a/core/modules/user/config/install/system.action.user_resend_action.yml b/core/modules/user/config/install/system.action.user_resend_action.yml
new file mode 100644
index 0000000000..0549f3ce2f
--- /dev/null
+++ b/core/modules/user/config/install/system.action.user_resend_action.yml
@@ -0,0 +1,10 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - user
+id: user_resend_action
+label: 'Resend welcome message the selected user(s)'
+type: user
+plugin: user_resend_action
+configuration: {  }
diff --git a/core/modules/user/config/schema/user.schema.yml b/core/modules/user/config/schema/user.schema.yml
index 2f9bda44f2..426d3cda77 100644
--- a/core/modules/user/config/schema/user.schema.yml
+++ b/core/modules/user/config/schema/user.schema.yml
@@ -150,6 +150,10 @@ action.configuration.user_remove_role_action:
       type: string
       label: 'The ID of the role to remove'
 
+action.configuration.user_resend_action:
+  type: action_configuration_default
+  label: 'Resend welcome message to selected users configuration'
+
 action.configuration.user_unblock_user_action:
   type: action_configuration_default
   label: 'Unblock the selected users configuration'
diff --git a/core/modules/user/src/Plugin/Action/ResendWelcomeMessage.php b/core/modules/user/src/Plugin/Action/ResendWelcomeMessage.php
new file mode 100644
index 0000000000..efc9f881cd
--- /dev/null
+++ b/core/modules/user/src/Plugin/Action/ResendWelcomeMessage.php
@@ -0,0 +1,112 @@
+<?php
+
+namespace Drupal\user\Plugin\Action;
+
+use Drupal\Core\Action\ActionBase;
+use Drupal\Core\Config\ConfigFactoryInterface;
+use Drupal\Core\Language\LanguageManagerInterface;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Drupal\Core\Session\AccountInterface;
+use Drupal\user\UserInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Resends welcome message to a user.
+ *
+ * @Action(
+ *   id = "user_resend_action",
+ *   label = @Translation("Resend welcome message to selected users"),
+ *   type = "user"
+ * )
+ */
+class ResendWelcomeMessage extends ActionBase implements ContainerFactoryPluginInterface {
+
+  /**
+   * The language manager.
+   *
+   * @var \Drupal\Core\Language\LanguageManagerInterface
+   */
+  protected $languageManager;
+
+  /**
+   * The user settings.
+   *
+   * @var \Drupal\Core\Config\ImmutableConfig
+   */
+  protected $userSettings;
+
+  /**
+   * Constructs a new ResendWelcomeMessage object.
+   *
+   * @param array $configuration
+   *   A configuration array containing information about the plugin instance.
+   * @param string $plugin_id
+   *   The plugin ID for the plugin instance.
+   * @param array $plugin_definition
+   *   The plugin implementation definition.
+   * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
+   *   The language manager.
+   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
+   *   The configuration factory.
+   */
+  public function __construct(array $configuration, $plugin_id, array $plugin_definition, LanguageManagerInterface $language_manager, ConfigFactoryInterface $config_factory) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition);
+    $this->languageManager = $language_manager;
+    $this->userSettings = $config_factory->get('user.settings');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('language_manager'),
+      $container->get('config.factory')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function execute($account = NULL) {
+    if (empty($account)) {
+      return;
+    }
+
+    $langcode = $this->languageManager->getCurrentLanguage()->getId();
+
+    if (!$account->isActive()) {
+      $op = 'register_pending_approval';
+    }
+    else {
+      // Determine the user approval method.
+      $config = \Drupal::getContainer()->get('config.factory')->get('user.settings');
+      switch ($config->get('register')) {
+        case UserInterface::REGISTER_ADMINISTRATORS_ONLY:
+          $op = 'register_admin_created';
+          break;
+
+        case UserInterface::REGISTER_VISITORS:
+        default:
+          $op = 'register_no_approval_required';
+      }
+    }
+
+    _user_mail_notify($op, $account);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) {
+    /** @var \Drupal\user\UserInterface $object */
+    $access = $object->status->access('edit', $account, TRUE)
+      ->andIf($object->access('update', $account, TRUE));
+
+    return $return_as_object ? $access : $access->isAllowed();
+  }
+
+}
diff --git a/core/modules/user/src/ProfileForm.php b/core/modules/user/src/ProfileForm.php
index a1e1550360..83e99a4d8b 100644
--- a/core/modules/user/src/ProfileForm.php
+++ b/core/modules/user/src/ProfileForm.php
@@ -25,6 +25,11 @@ protected function actions(array $form, FormStateInterface $form_state) {
     $element['delete']['#submit'] = ['::editCancelSubmit'];
     $element['delete']['#access'] = $account->id() > 1 && $account->access('delete');
 
+    $element['resend']['#type'] = 'submit';
+    $element['resend']['#value'] = $account->isActive() ? $this->t('Resend welcome message') : $this->t('Resend awaiting approval message');
+    $element['resend']['#submit'] = ['::editResendSubmit'];
+    $element['resend']['#access'] = $account->getEmail() && $this->currentUser()->hasPermission('administer users');
+
     return $element;
   }
 
@@ -57,4 +62,42 @@ public function editCancelSubmit($form, FormStateInterface $form_state) {
     );
   }
 
+  /**
+   * Provides a submit handler for the 'Re-send welcome message' button.
+   */
+  public function editResendSubmit(array $form, FormStateInterface $form_state) {
+    $account = $this->entity;
+    $langcode = $this->languageManager->getCurrentLanguage()->getId();
+
+    if (!$account->isActive()) {
+      $op = 'register_pending_approval';
+    }
+    else {
+      // Determine the user approval method.
+      $config = \Drupal::getContainer()->get('config.factory')->get('user.settings');
+      switch ($config->get('register')) {
+        case UserInterface::REGISTER_ADMINISTRATORS_ONLY:
+          $op = 'register_admin_created';
+          break;
+
+        case UserInterface::REGISTER_VISITORS:
+        default:
+          $op = 'register_no_approval_required';
+      }
+    }
+
+    // Notify the user via email.
+    $mail = _user_mail_notify($op, $account, $langcode);
+
+    // Log the mail.
+    if (!empty($mail)) {
+      $this->getLogger('user')->notice('Welcome message has been re-sent to %name at %email.', ['%name' => $account->getAccountName(), '%email' => $account->getEmail()]);
+      $this->messenger()->addMessage($this->t('Welcome message has been re-sent to %name at %email', ['%name' => $account->getAccountName(), '%email' => $account->getEmail()]));
+    }
+    else {
+      $this->getLogger('user')->notice('There was an error re-sending welcome message to %name at %email', ['%name' => $account->getAccountName(), '%email' => $account->getEmail()]);
+      $this->messenger()->addMessage($this->t('There was an error re-sending welcome message to %name at %email', ['%name' => $account->getAccountName(), '%email' => $account->getEmail()]), 'error');
+    }
+  }
+
 }
diff --git a/core/modules/user/tests/src/Functional/UserAdminTest.php b/core/modules/user/tests/src/Functional/UserAdminTest.php
index d870ba56e2..f8c89e8c55 100644
--- a/core/modules/user/tests/src/Functional/UserAdminTest.php
+++ b/core/modules/user/tests/src/Functional/UserAdminTest.php
@@ -117,13 +117,13 @@ public function testUserAdmin() {
     $account = $user_storage->load($user_c->id());
     $this->assertTrue($account->isBlocked(), 'User C blocked');
 
-    // Test filtering on admin page for blocked users
+    // Test filtering on admin page for blocked users.
     $this->drupalGet('admin/people', ['query' => ['status' => 2]]);
     $this->assertNoText($user_a->getAccountName(), 'User A not on filtered by status on admin users page');
     $this->assertNoText($user_b->getAccountName(), 'User B not on filtered by status on admin users page');
     $this->assertText($user_c->getAccountName(), 'User C on filtered by status on admin users page');
 
-    // Test unblocking of a user from /admin/people page and sending of activation mail
+    // Test unblocking of a user from /admin/people page and sending of activation mail.
     $editunblock = [];
     $editunblock['action'] = 'user_unblock_user_action';
     $editunblock['user_bulk_form[4]'] = TRUE;
@@ -137,7 +137,7 @@ public function testUserAdmin() {
     $this->assertTrue($account->isActive(), 'User C unblocked');
     $this->assertMail("to", $account->getEmail(), "Activation mail sent to user C");
 
-    // Test blocking and unblocking another user from /user/[uid]/edit form and sending of activation mail
+    // Test blocking and unblocking another user from /user/[uid]/edit form and sending of activation mail.
     $user_d = $this->drupalCreateUser([]);
     $user_storage->resetCache([$user_d->id()]);
     $account1 = $user_storage->load($user_d->id());
@@ -203,4 +203,188 @@ public function testNotificationEmailAddress() {
     $this->assertTrue(count($user_mail), 'New user mail to user is sent from configured Notification Email address');
   }
 
+  /**
+   * Tests the resending of a welcome e-mail notification.
+   *
+   * @dataProvider welcomeNotifications
+   */
+  public function testResendWelcomeEmailNotification($register_mode, $mail_id) {
+    $admin_user = $this->drupalCreateUser(['administer users']);
+    $this->drupalLogin($admin_user);
+
+    $config = $this->config('user.settings');
+    $config
+      ->set('register', $register_mode)
+      ->save();
+
+    // Create an active user.
+    $test_user = $this->drupalCreateUser();
+    $test_user->save();
+
+    // Resend a alternate welcome message.
+    $this->drupalPostForm('user/' . $test_user->id() . '/edit', ['status' => 0], t('Resend welcome message'));
+    $mails = $this->getMails();
+
+    // Assert only the user receive a mail.
+    $this->assertCount(1, $mails);
+
+    $this->assertEquals($mails[0]['to'], $test_user->getEmail(), 'Activation mail resend to user');
+    $this->assertEquals($mails[0]['id'], $mail_id);
+  }
+
+  /**
+   * Collection of alternatives registrations configurations.
+   *
+   * @return array
+   *   List of registration config & expected user mail.
+   */
+  public function welcomeNotifications() {
+    return [
+      [
+        UserInterface::REGISTER_VISITORS,
+        'user_register_no_approval_required',
+      ],
+      [
+        UserInterface::REGISTER_ADMINISTRATORS_ONLY,
+        'user_register_admin_created',
+      ],
+      [
+        UserInterface::REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL,
+        'user_register_no_approval_required',
+      ],
+    ];
+  }
+
+  /**
+   * Tests the resending of a waiting approval e-mail notification.
+   *
+   * @dataProvider awaitingApprovalNotifications
+   */
+  public function testResendAwaitingApprovalEmailNotification($register_mode, $mail_id) {
+    $admin_user = $this->drupalCreateUser(['administer users']);
+    $this->drupalLogin($admin_user);
+
+    $config = $this->config('user.settings');
+    $config
+      ->set('register', $register_mode)
+      ->save();
+
+    // Create a blocked user.
+    $blocked_user = $this->drupalCreateUser()->block();
+    $blocked_user->save();
+
+    $this->drupalPostForm('user/' . $blocked_user->id() . '/edit', ['status' => 0], t('Resend awaiting approval message'));
+    $mails = $this->getMails();
+
+    // Assert the blocked user & admin receive a mail.
+    $this->assertCount(2, $mails);
+    $this->assertEquals($mails[0]['to'], $blocked_user->getEmail(), 'Awaiting approval mail resend to user');
+    $this->assertEquals($mails[0]['id'], $mail_id);
+    $this->assertEquals($mails[1]['to'], 'simpletest@example.com', 'Pending admin approval mail resend to admin');
+    $this->assertEquals($mails[1]['id'], 'user_register_pending_approval_admin');
+  }
+
+  /**
+   * Collection of alternatives registrations configurations.
+   *
+   * @return array
+   *   List of registration config & expected user mail.
+   */
+  public function awaitingApprovalNotifications() {
+    return [
+      [
+        UserInterface::REGISTER_VISITORS,
+        'user_register_pending_approval',
+      ],
+      [
+        UserInterface::REGISTER_ADMINISTRATORS_ONLY,
+        'user_register_pending_approval',
+      ],
+      [
+        UserInterface::REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL,
+        'user_register_pending_approval',
+      ],
+    ];
+  }
+
+  /**
+   * Tests the bulk action resending of welcome e-mails notification.
+   */
+  public function testBulkResendWelcomeEmailsNotifications() {
+    $admin_user = $this->drupalCreateUser(['administer users']);
+    $this->drupalLogin($admin_user);
+
+    // Create users at a certain timestamp to fix order of "Member for".
+    $user_a = $this->drupalCreateUser();
+    $user_a->created = 1363219200;
+    $user_a->save();
+    $user_b = $this->drupalCreateUser();
+    $user_b->created = 1394755200;
+    $user_b->save();
+    $user_c = $this->drupalCreateUser();
+    $user_c->created = 1426291200;
+    $user_c->save();
+
+    // Resend welcome mail to user_c & user_b.
+    $edit = [
+      'action'            => 'user_resend_action',
+      'user_bulk_form[3]' => TRUE,
+      'user_bulk_form[2]' => TRUE,
+    ];
+    $this->drupalPostForm('admin/people', $edit, t('Apply to selected items'));
+    $mails = $this->getMails();
+
+    // Assert only 2 accounts have been notified.
+    $this->assertCount(2, $mails);
+    $this->assertEquals($mails[0]['to'], $user_c->getEmail(), 'Activation mail resend to user C');
+    $this->assertEquals($mails[0]['id'], 'user_register_no_approval_required');
+    $this->assertEquals($mails[1]['to'], $user_b->getEmail(), 'Activation mail resend to user B');
+    $this->assertEquals($mails[1]['id'], 'user_register_no_approval_required');
+  }
+
+  /**
+   * Tests the bulk action resending of waiting approval e-mails notification.
+   */
+  public function testBulkResendAwaitingApprovalEmailNotification() {
+    $admin_user = $this->drupalCreateUser(['administer users']);
+    $this->drupalLogin($admin_user);
+
+    // Create users at a certain timestamp to fix order of "Member for".
+    $user_a = $this->drupalCreateUser()->block();
+    $user_a->created = 1363219200;
+    $user_a->save();
+    $user_b = $this->drupalCreateUser()->block();
+    $user_b->created = 1394755200;
+    $user_b->save();
+    $user_c = $this->drupalCreateUser()->block();
+    $user_c->created = 1426291200;
+    $user_c->save();
+
+    // Resend waiting approval mail to user_c & user_b.
+    $edit = [
+      'action'            => 'user_resend_action',
+      'user_bulk_form[3]' => TRUE,
+      'user_bulk_form[2]' => TRUE,
+    ];
+    $this->drupalPostForm('admin/people', $edit, t('Apply to selected items'));
+    $mails = $this->getMails();
+
+    // Assert only 2 accounts & admin have been notified.
+    // The admin should be notified twice.
+    $this->assertCount(4, $mails);
+
+    // Awaiting approval mail resend to user C.
+    $this->assertEquals($mails[0]['id'], 'user_register_pending_approval');
+    $this->assertEquals($mails[0]['to'], $user_c->getEmail(), 'Awaiting approval mail resend to user C');
+    // Admin notification about user C notification resend.
+    $this->assertEquals($mails[1]['id'], 'user_register_pending_approval_admin');
+    $this->assertEquals($mails[1]['to'], 'simpletest@example.com', 'Pending admin approval mail resend to admin');
+    // Awaiting approval mail resend to user B.
+    $this->assertEquals($mails[2]['id'], 'user_register_pending_approval');
+    $this->assertEquals($mails[2]['to'], $user_b->getEmail(), 'Awaiting approval mail resend to user B');
+    // Admin notification about user B notification resend.
+    $this->assertEquals($mails[3]['id'], 'user_register_pending_approval_admin');
+    $this->assertEquals($mails[3]['to'], 'simpletest@example.com', 'Pending admin approval mail resend to admin');
+  }
+
 }
diff --git a/core/modules/user/user.install b/core/modules/user/user.install
index 2540ac2cd3..573e777607 100644
--- a/core/modules/user/user.install
+++ b/core/modules/user/user.install
@@ -5,6 +5,8 @@
  * Install, update and uninstall functions for the user module.
  */
 
+use Drupal\system\Entity\Action;
+
 /**
  * Implements hook_schema().
  */
@@ -103,3 +105,17 @@ function user_update_8100() {
     $config->set('status_blocked', $mail)->save(TRUE);
   }
 }
+
+/**
+ * Add an action to resend activation emails to multiple users.
+ */
+function user_update_8700() {
+  $action = Action::create([
+    'id' => 'user_resend_action',
+    'type' => 'user',
+    'label' => t('Resend welcome message the selected user(s)'),
+    'configuration' => [],
+    'plugin' => 'user_resend_action',
+  ]);
+  $action->trustData()->save();
+}
