diff --git a/automatic_updates.info.yml b/automatic_updates.info.yml
index 5488d289eb0e3a1b41512b8b16d5403fc562d9cf..5f79eeb10cbcd43d73db8dd2df1608add9aa4a02 100644
--- a/automatic_updates.info.yml
+++ b/automatic_updates.info.yml
@@ -1,8 +1,8 @@
 name: 'Automatic Updates'
 type: module
-description: 'Drupal Automatic Updates'
+description: 'Display public service announcements and verify readiness for applying automatic updates to the site.'
 core: 8.x
 package: 'Security'
-configure: automatic_updates.admin_form
+configure: automatic_updates.settings
 dependencies:
   - drupal:update
diff --git a/automatic_updates.install b/automatic_updates.install
index 10f6b1155e38eb521bd6f3d67aab64a9246041ec..fa355df4bee5fe00d224c8aec5a132618b89bb24 100644
--- a/automatic_updates.install
+++ b/automatic_updates.install
@@ -19,13 +19,13 @@ function automatic_updates_requirements() {
   $psa = \Drupal::service('automatic_updates.psa');
   $messages = $psa->getPublicServiceMessages();
   $requirements['automatic_updates_psa'] = [
-    'title' => t('Drupal public service announcements'),
+    'title' => t('<a href="@link">Drupal public service announcements</a>', ['@link' => 'https://www.drupal.org/docs/8/update/automatic-updates#psas']),
     'severity' => REQUIREMENT_OK,
     'value' => t('No announcements requiring attention.'),
   ];
   if (!empty($messages)) {
     $requirements['automatic_updates_psa']['severity'] = REQUIREMENT_ERROR;
-    $requirements['automatic_updates_psa']['value'] = new PluralTranslatableMarkup(count($messages), '@count urgent announcement requiring your attention:', '@count urgent announcements requiring your attention:');
+    $requirements['automatic_updates_psa']['value'] = new PluralTranslatableMarkup(count($messages), '@count urgent announcement requires your attention:', '@count urgent announcements require your attention:');
     $requirements['automatic_updates_psa']['description'] = [
       '#theme' => 'item_list',
       '#items' => $messages,
diff --git a/automatic_updates.links.menu.yml b/automatic_updates.links.menu.yml
index 572208f91e730a4b8fa20243ad331fb2cb0ec495..4ebb874894f1e20b39aedf4f6a14b64dcc54885c 100644
--- a/automatic_updates.links.menu.yml
+++ b/automatic_updates.links.menu.yml
@@ -1,5 +1,5 @@
-automatic_updates.admin_form:
-  title: 'Automatic Updates'
-  route_name: automatic_updates.admin_form
-  description: 'Configure automatic updates'
+automatic_updates.settings:
+  title: 'Automatic updates'
+  route_name: automatic_updates.settings
+  description: 'Configure public service announcement notifications'
   parent: system.admin_config_system
diff --git a/automatic_updates.module b/automatic_updates.module
index 34ea03297fc0e2509cca0b8d44b664a4df258af2..65d6557ea1f6bc13f51376b2641f7437ecf13b54 100644
--- a/automatic_updates.module
+++ b/automatic_updates.module
@@ -31,8 +31,45 @@ function automatic_updates_page_top(array &$page_top) {
     }
     /** @var \Drupal\automatic_updates\Services\AutomaticUpdatesPsaInterface $psa */
     $psa = \Drupal::service('automatic_updates.psa');
-    foreach ($psa->getPublicServiceMessages() as $psa) {
-      \Drupal::messenger()->addError($psa);
+    $messages = $psa->getPublicServiceMessages();
+    if ($messages) {
+      \Drupal::messenger()->addError(t('Drupal public service announcements:'));
+      foreach ($messages as $message) {
+        \Drupal::messenger()->addError($message);
+      }
     }
   }
 }
+
+/**
+ * Implements hook_theme().
+ */
+function automatic_updates_theme(array $existing, $type, $theme, $path) {
+  return [
+    'automatic_updates_psa_notify' => [
+      'variables' => [
+        'messages' => [],
+      ],
+    ],
+  ];
+}
+
+/**
+ * Implements hook_cron().
+ */
+function automatic_updates_cron() {
+  /** @var \Drupal\automatic_updates\Services\NotifyInterface $notify */
+  $notify = \Drupal::service('automatic_updates.psa_notify');
+  $notify->send();
+}
+
+/**
+ * Implements hook_mail().
+ */
+function automatic_updates_mail($key, &$message, $params) {
+  /** @var \Drupal\Core\Render\RendererInterface $renderer */
+  $renderer = \Drupal::service('renderer');
+
+  $message['subject'] = $params['subject'];
+  $message['body'][] = $renderer->render($params['body']);
+}
diff --git a/automatic_updates.routing.yml b/automatic_updates.routing.yml
index 18c08689d0f6a0b086273fcc65769e535a2dc121..921723373c902d5218b0f8922f88c58611a74da8 100644
--- a/automatic_updates.routing.yml
+++ b/automatic_updates.routing.yml
@@ -1,7 +1,7 @@
-automatic_updates.admin_form:
+automatic_updates.settings:
   path: '/admin/config/automatic_updates'
   defaults:
-    _form: '\Drupal\automatic_updates\Form\AdminForm'
+    _form: '\Drupal\automatic_updates\Form\SettingsForm'
     _title: 'Automatic Updates'
   requirements:
     _permission: 'administer software updates'
diff --git a/automatic_updates.services.yml b/automatic_updates.services.yml
index 26d646aca95ac75c9a7d6c87d23cd4daa7a498d1..31378b58ada5005c6b7e842b6633cd3c816e278f 100644
--- a/automatic_updates.services.yml
+++ b/automatic_updates.services.yml
@@ -13,3 +13,14 @@ services:
       - '@extension.list.profile'
       - '@extension.list.theme'
       - '@logger.channel.automatic_updates'
+  automatic_updates.psa_notify:
+    class: Drupal\automatic_updates\Services\Notify
+    arguments:
+      - '@plugin.manager.mail'
+      - '@automatic_updates.psa'
+      - '@config.factory'
+      - '@language_manager'
+      - '@state'
+      - '@datetime.time'
+      - '@entity_type.manager'
+      - '@string_translation'
diff --git a/config/install/automatic_updates.settings.yml b/config/install/automatic_updates.settings.yml
index 085f065b0fc5d65c35a4eec635f6ca89cab69fd4..93299fe027ec6460fa820f459a69b2c052ae9eca 100644
--- a/config/install/automatic_updates.settings.yml
+++ b/config/install/automatic_updates.settings.yml
@@ -3,3 +3,5 @@
 # https://www.drupal.org/project/automatic_updates/issues/3045273
 psa_endpoint: 'http://localhost/automatic_updates/test-json'
 enable_psa: true
+notify: true
+check_frequency: 43200
diff --git a/config/schema/automatic_updates.schema.yml b/config/schema/automatic_updates.schema.yml
index ca294031e24d9d8350c77d967c1eb41ac11471fd..788c36a34da3a52c64a98713b8d56f0e1e149f0a 100644
--- a/config/schema/automatic_updates.schema.yml
+++ b/config/schema/automatic_updates.schema.yml
@@ -8,3 +8,9 @@ automatic_updates.settings:
     enable_psa:
       type: boolean
       label: 'Enable PSA notices'
+    notify:
+      type: boolean
+      label: 'Notify when PSAs are available'
+    check_frequency:
+      type: integer
+      label: 'Frequency to check for PSAs, defaults to 12 hours'
diff --git a/src/Form/AdminForm.php b/src/Form/SettingsForm.php
similarity index 57%
rename from src/Form/AdminForm.php
rename to src/Form/SettingsForm.php
index 78217e8bc78230de5b469bfcbd9117ea6cc607c4..112a67ce110d543ddd70c0c5160245ca78ea0ed3 100644
--- a/src/Form/AdminForm.php
+++ b/src/Form/SettingsForm.php
@@ -4,11 +4,12 @@ namespace Drupal\automatic_updates\Form;
 
 use Drupal\Core\Form\ConfigFormBase;
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Url;
 
 /**
- * Administration form for automatic updates.
+ * Settings form for automatic updates.
  */
-class AdminForm extends ConfigFormBase {
+class SettingsForm extends ConfigFormBase {
 
   /**
    * {@inheritdoc}
@@ -31,11 +32,20 @@ class AdminForm extends ConfigFormBase {
    */
   public function buildForm(array $form, FormStateInterface $form_state) {
     $config = $this->config('automatic_updates.settings');
+    $form['description'] = [
+      '#markup' => '<p>' . $this->t('Public service announcements are compared against the entire code for the site, not just installed extensions.') . '</p>',
+    ];
     $form['enable_psa'] = [
       '#type' => 'checkbox',
-      '#title' => $this->t('Enable messaging of public service alerts (PSAs)'),
+      '#title' => $this->t('Show public service announcements on administrative pages.'),
       '#default_value' => $config->get('enable_psa'),
     ];
+    $form['notify'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Send email notifications for public service announcements.'),
+      '#default_value' => $config->get('notify'),
+      '#description' => $this->t('The email addresses listed in <a href="@update_manager">update manager settings</a> will be notified.', ['@update_manager' => Url::fromRoute('update.settings')->toString()]),
+    ];
     return parent::buildForm($form, $form_state);
   }
 
diff --git a/src/Services/AutomaticUpdatesPsa.php b/src/Services/AutomaticUpdatesPsa.php
index bc33939f525f49a095186d0b1f3f867dc75bc36e..820bc9955bd088ab2547252d8dd80e4ff55f617a 100644
--- a/src/Services/AutomaticUpdatesPsa.php
+++ b/src/Services/AutomaticUpdatesPsa.php
@@ -4,6 +4,7 @@ namespace Drupal\automatic_updates\Services;
 
 use Composer\Semver\VersionParser;
 use Drupal\Component\Datetime\TimeInterface;
+use Drupal\Component\Render\FormattableMarkup;
 use Drupal\Component\Version\Constraint;
 use Drupal\Core\Cache\CacheBackendInterface;
 use Drupal\Core\Config\ConfigFactoryInterface;
@@ -22,7 +23,7 @@ class AutomaticUpdatesPsa implements AutomaticUpdatesPsaInterface {
   use DependencySerializationTrait;
 
   /**
-   * Module's configuration.
+   * This module's configuration.
    *
    * @var \Drupal\Core\Config\ImmutableConfig
    */
@@ -122,13 +123,12 @@ class AutomaticUpdatesPsa implements AutomaticUpdatesPsaInterface {
       $response = $cache->data;
     }
     else {
+      $psa_endpoint = $this->config->get('psa_endpoint');
       try {
-        $psa_endpoint = $this->config->get('psa_endpoint');
         $response = $this->httpClient->get($psa_endpoint)
           ->getBody()
           ->getContents();
-        // Set response in cache for 12 hours.
-        $this->cache->set('automatic_updates_psa', $response, $this->time->getCurrentTime() + 3600 * 12);
+        $this->cache->set('automatic_updates_psa', $response, $this->time->getCurrentTime() + $this->config->get('check_frequency'));
       }
       catch (TransferException $exception) {
         $this->logger->error($exception->getMessage());
@@ -138,14 +138,21 @@ class AutomaticUpdatesPsa implements AutomaticUpdatesPsaInterface {
 
     try {
       $json_payload = json_decode($response);
-      foreach ($json_payload as $json) {
-        if ($json->project === 'core') {
-          $this->coreParser($messages, $json);
-        }
-        else {
-          $this->contribParser($messages, $json);
+      if ($json_payload) {
+        foreach ($json_payload as $json) {
+          if ($json->project === 'core') {
+            $this->coreParser($messages, $json);
+          }
+          else {
+            $this->contribParser($messages, $json);
+          }
         }
       }
+      else {
+        $this->logger->error('Drupal PSA JSON is malformed: @response', ['@response' => $response]);
+        $messages[] = $this->t('Drupal PSA JSON is malformed.');
+      }
+
     }
     catch (\UnexpectedValueException $exception) {
       $this->logger->error($exception->getMessage());
@@ -172,7 +179,7 @@ class AutomaticUpdatesPsa implements AutomaticUpdatesPsaInterface {
     $psa_constraint = $parser->parseConstraints($version_string);
     $core_constraint = $parser->parseConstraints(\Drupal::VERSION);
     if ($psa_constraint->matches($core_constraint)) {
-      $messages[] = $this->t('Drupal Core PSA: <a href=":url">:message</a>', [
+      $messages[] = new FormattableMarkup('<a href=":url">:message</a>', [
         ':message' => $json->title,
         ':url' => $json->link,
       ]);
@@ -223,7 +230,7 @@ class AutomaticUpdatesPsa implements AutomaticUpdatesPsaInterface {
     $version_string = implode('||', $json->secure_versions);
     $constraint = new Constraint("<=$extension_version", \Drupal::CORE_COMPATIBILITY);
     if (!$constraint->isCompatible($version_string)) {
-      $messages[] = $this->t('Drupal Contrib Project PSA: <a href=":url">:message</a>', [
+      $messages[] = new FormattableMarkup('<a href=":url">:message</a>', [
         ':message' => $json->title,
         ':url' => $json->link,
       ]);
diff --git a/src/Services/Notify.php b/src/Services/Notify.php
new file mode 100644
index 0000000000000000000000000000000000000000..3650080bfd9f739dcc4dad4b6ff1555636f74cfd
--- /dev/null
+++ b/src/Services/Notify.php
@@ -0,0 +1,160 @@
+<?php
+
+namespace Drupal\automatic_updates\Services;
+
+use Drupal\Component\Datetime\TimeInterface;
+use Drupal\Core\Config\ConfigFactoryInterface;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Language\LanguageManagerInterface;
+use Drupal\Core\Mail\MailManagerInterface;
+use Drupal\Core\State\StateInterface;
+use Drupal\Core\StringTranslation\PluralTranslatableMarkup;
+use Drupal\Core\StringTranslation\StringTranslationTrait;
+use Drupal\Core\StringTranslation\TranslationInterface;
+
+/**
+ * Class EmailNotify.
+ */
+class Notify implements NotifyInterface {
+  use StringTranslationTrait;
+
+  /**
+   * Mail manager.
+   *
+   * @var \Drupal\Core\Mail\MailManagerInterface
+   */
+  protected $mailManager;
+
+  /**
+   * The automatic updates service.
+   *
+   * @var \Drupal\automatic_updates\Services\AutomaticUpdatesPsaInterface
+   */
+  protected $automaticUpdatesPsa;
+
+  /**
+   * The config factory.
+   *
+   * @var \Drupal\Core\Config\ConfigFactoryInterface
+   */
+  protected $configFactory;
+
+  /**
+   * The language manager.
+   *
+   * @var \Drupal\Core\Language\LanguageManagerInterface
+   */
+  protected $languageManager;
+
+  /**
+   * The state service.
+   *
+   * @var \Drupal\Core\State\StateInterface
+   */
+  protected $state;
+
+  /**
+   * The time service.
+   *
+   * @var \Drupal\Component\Datetime\TimeInterface
+   */
+  protected $time;
+
+  /**
+   * Entity type manager.
+   *
+   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
+   */
+  protected $entityTypeManager;
+
+  /**
+   * Event dispatcher.
+   *
+   * @var \Symfony\Component\EventDispatcher\EventDispatcherInterface
+   */
+  protected $eventDispatcher;
+
+  /**
+   * EmailNotify constructor.
+   *
+   * @param \Drupal\Core\Mail\MailManagerInterface $mail_manager
+   *   The mail manager.
+   * @param \Drupal\automatic_updates\Services\AutomaticUpdatesPsaInterface $automatic_updates_psa
+   *   The automatic updates service.
+   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
+   *   The config factory.
+   * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
+   *   The language manager.
+   * @param \Drupal\Core\State\StateInterface $state
+   *   The state service.
+   * @param \Drupal\Component\Datetime\TimeInterface $time
+   *   The time service.
+   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
+   *   Entity type manager.
+   * @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation
+   *   The string translation service.
+   */
+  public function __construct(MailManagerInterface $mail_manager, AutomaticUpdatesPsaInterface $automatic_updates_psa, ConfigFactoryInterface $config_factory, LanguageManagerInterface $language_manager, StateInterface $state, TimeInterface $time, EntityTypeManagerInterface $entity_type_manager, TranslationInterface $string_translation) {
+    $this->mailManager = $mail_manager;
+    $this->automaticUpdatesPsa = $automatic_updates_psa;
+    $this->configFactory = $config_factory;
+    $this->languageManager = $language_manager;
+    $this->state = $state;
+    $this->time = $time;
+    $this->entityTypeManager = $entity_type_manager;
+    $this->stringTranslation = $string_translation;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function send() {
+    $messages = $this->automaticUpdatesPsa->getPublicServiceMessages();
+    if (!$messages) {
+      return;
+    }
+    $notify_list = $this->configFactory->get('update.settings')->get('notification.emails');
+    if (!empty($notify_list)) {
+      $frequency = $this->configFactory->get('automatic_updates.settings')->get('check_frequency');
+      $last_check = $this->state->get('automatic_updates.last_check') ?: 0;
+      if (($this->time->getRequestTime() - $last_check) > $frequency) {
+        $this->state->set('automatic_updates.last_check', $this->time->getRequestTime());
+
+        $params['subject'] = new PluralTranslatableMarkup(
+          count($messages),
+          '@count urgent Drupal announcement requires your attention for @site_name',
+          '@count urgent Drupal announcements require your attention for @site_name',
+          ['@site_name' => $this->configFactory->get('system.site')->get('name')]
+        );
+        $params['body'] = [
+          '#theme' => 'automatic_updates_psa_notify',
+          '#messages' => $messages,
+        ];
+        $default_langcode = $this->languageManager->getDefaultLanguage()->getId();
+        $params['langcode'] = $default_langcode;
+        foreach ($notify_list as $to) {
+          $this->doSend($to, $params);
+        }
+      }
+    }
+  }
+
+  /**
+   * Composes and send the email message.
+   *
+   * @param string $to
+   *   The email address where the message will be sent.
+   * @param array $params
+   *   Parameters to build the email.
+   */
+  protected function doSend($to, array $params) {
+    $users = $this->entityTypeManager->getStorage('user')
+      ->loadByProperties(['mail' => $to]);
+    if ($users) {
+      $to_user = reset($users);
+      $params['langcode'] = $to_user->getPreferredLangcode();
+    }
+    $this->mailManager->mail('automatic_updates', 'notify', $to, $params['langcode'], $params);
+  }
+
+}
diff --git a/src/Services/NotifyInterface.php b/src/Services/NotifyInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..aee5b3ba8745b531887134f34bd0a0789aa23b8b
--- /dev/null
+++ b/src/Services/NotifyInterface.php
@@ -0,0 +1,15 @@
+<?php
+
+namespace Drupal\automatic_updates\Services;
+
+/**
+ * Interface NotifyInterface.
+ */
+interface NotifyInterface {
+
+  /**
+   * Send notification when PSAs are available.
+   */
+  public function send();
+
+}
diff --git a/templates/automatic-updates-psa-notify.html.twig b/templates/automatic-updates-psa-notify.html.twig
new file mode 100644
index 0000000000000000000000000000000000000000..5bd8a9062eaa1c8bb6cf92138d5ee531478e9482
--- /dev/null
+++ b/templates/automatic-updates-psa-notify.html.twig
@@ -0,0 +1,35 @@
+{#
+/**
+ * @file
+ * Template for the public service annoucements email notification.
+ *
+ * Available variables:
+ * - messages: The messages array
+ *
+ * @ingroup themeable
+ */
+#}
+
+<p>
+  {% trans %}
+    A security update will be made available soon for your Drupal site. To ensure the security of the site, you should prepare the site to immediately install the update once it is released!
+  {% endtrans %}
+</p>
+<p>
+  {% set status_report = path('system.status') %}
+  {% trans %}
+    See the <a href="{{ status_report }}">site status report page</a> for more information.
+  {% endtrans %}
+</p>
+<p>{{ 'Drupal public service announcements:'|t }}</p>
+<ul>
+  {% for message in messages %}
+    <li>{{ message }}</li>
+  {% endfor %}
+</ul>
+<p>
+  {% set settings_link = path('automatic_updates.settings') %}
+  {% trans %}
+    Your site is currently configured to send these emails when a security update will be made available soon. To change how you are notified, you may <a href="{{ settings_link }}">configure email notifications</a>.
+  {% endtrans %}
+</p>
diff --git a/tests/src/Functional/AutomaticUpdatesTest.php b/tests/src/Functional/AutomaticUpdatesTest.php
index 4b16bc6e9969be1f3b029ff0cb1d4cf83159ad0c..b682a3a3f7a0e0353bde566371a8e5993202a12b 100644
--- a/tests/src/Functional/AutomaticUpdatesTest.php
+++ b/tests/src/Functional/AutomaticUpdatesTest.php
@@ -13,11 +13,9 @@ use Drupal\Tests\BrowserTestBase;
 class AutomaticUpdatesTest extends BrowserTestBase {
 
   /**
-   * Modules to enable.
-   *
-   * @var array
+   * {@inheritdoc}
    */
-  public static $modules = [
+  protected static $modules = [
     'automatic_updates',
     'test_automatic_updates',
     'update',
@@ -46,20 +44,21 @@ class AutomaticUpdatesTest extends BrowserTestBase {
    * Tests that a PSA is displayed.
    */
   public function testPsa() {
+    // Setup test PSA endpoint.
     $end_point = $this->buildUrl(Url::fromRoute('test_automatic_updates.json_test_controller'));
     $this->config('automatic_updates.settings')
       ->set('psa_endpoint', $end_point)
       ->save();
     $this->drupalGet(Url::fromRoute('system.admin'));
-    $this->assertSession()->pageTextContains('Drupal Core PSA: Critical Release - PSA-2019-02-19');
-    $this->assertSession()->pageTextNotContains('Drupal Core PSA: Critical Release - PSA-Really Old');
-    $this->assertSession()->pageTextNotContains('Drupal Contrib Project PSA: Node - Moderately critical - Access bypass - SA-CONTRIB-2019');
-    $this->assertSession()->pageTextContains('Drupal Contrib Project PSA: Seven - Moderately critical - Access bypass - SA-CONTRIB-2019');
-    $this->assertSession()->pageTextContains('Drupal Contrib Project PSA: Standard - Moderately critical - Access bypass - SA-CONTRIB-2019');
+    $this->assertSession()->pageTextContains('Critical Release - PSA-2019-02-19');
+    $this->assertSession()->pageTextNotContains('Critical Release - PSA-Really Old');
+    $this->assertSession()->pageTextNotContains('Node - Moderately critical - Access bypass - SA-CONTRIB-2019');
+    $this->assertSession()->pageTextContains('Seven - Moderately critical - Access bypass - SA-CONTRIB-2019');
+    $this->assertSession()->pageTextContains('Standard - Moderately critical - Access bypass - SA-CONTRIB-2019');
 
     // Test site status report.
     $this->drupalGet(Url::fromRoute('system.status'));
-    $this->assertSession()->pageTextContains('3 urgent announcements requiring your attention:');
+    $this->assertSession()->pageTextContains('3 urgent announcements require your attention:');
 
     // Test cache.
     $end_point = 'http://localhost/automatic_updates/test-json-denied';
@@ -67,7 +66,7 @@ class AutomaticUpdatesTest extends BrowserTestBase {
       ->set('psa_endpoint', $end_point)
       ->save();
     $this->drupalGet(Url::fromRoute('system.admin'));
-    $this->assertSession()->pageTextContains('Drupal Core PSA: Critical Release - PSA-2019-02-19');
+    $this->assertSession()->pageTextContains('Critical Release - PSA-2019-02-19');
 
     // Test transmit errors with JSON endpoint.
     drupal_flush_all_caches();
@@ -82,9 +81,9 @@ class AutomaticUpdatesTest extends BrowserTestBase {
       ->save();
     drupal_flush_all_caches();
     $this->drupalGet(Url::fromRoute('system.admin'));
-    $this->assertSession()->pageTextNotContains('Drupal Core PSA: Critical Release - PSA-2019-02-19');
+    $this->assertSession()->pageTextNotContains('Critical Release - PSA-2019-02-19');
     $this->drupalGet(Url::fromRoute('system.status'));
-    $this->assertSession()->pageTextNotContains('4 announcements requiring your attention:');
+    $this->assertSession()->pageTextNotContains('urgent announcements require your attention');
   }
 
 }
diff --git a/tests/src/Functional/NotifyTest.php b/tests/src/Functional/NotifyTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..dfb394ccb801e8e30939cfbb0cc476d6872157d2
--- /dev/null
+++ b/tests/src/Functional/NotifyTest.php
@@ -0,0 +1,82 @@
+<?php
+
+namespace Drupal\Tests\automatic_updates\Functional;
+
+use Drupal\Core\StringTranslation\StringTranslationTrait;
+use Drupal\Core\Test\AssertMailTrait;
+use Drupal\Core\Url;
+use Drupal\Tests\BrowserTestBase;
+
+/**
+ * Tests notification emails for PSAs.
+ *
+ * @group automatic_updates
+ */
+class NotifyTest extends BrowserTestBase {
+  use AssertMailTrait;
+  use StringTranslationTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $modules = [
+    'automatic_updates',
+    'test_automatic_updates',
+    'update',
+  ];
+
+  /**
+   * A user with permission to administer site configuration.
+   *
+   * @var \Drupal\user\UserInterface
+   */
+  protected $user;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    // Setup test PSA endpoint.
+    $end_point = $this->buildUrl(Url::fromRoute('test_automatic_updates.json_test_controller'));
+    $this->config('automatic_updates.settings')
+      ->set('psa_endpoint', $end_point)
+      ->save();
+    // Setup a default destination email address.
+    $this->config('update.settings')
+      ->set('notification.emails', ['admin@example.com'])
+      ->save();
+
+    $this->user = $this->drupalCreateUser([
+      'administer site configuration',
+      'access administration pages',
+    ]);
+    $this->drupalLogin($this->user);
+  }
+
+  /**
+   * Tests sending email notifications.
+   */
+  public function testSendMail() {
+    // Test PSAs on admin pages.
+    $this->drupalGet(Url::fromRoute('system.admin'));
+    $this->assertSession()->pageTextContains('Critical Release - PSA-2019-02-19');
+
+    // Email should be sent.
+    $notify = $this->container->get('automatic_updates.psa_notify');
+    $notify->send();
+    $this->assertCount(1, $this->getMails());
+    $this->assertMailString('subject', '3 urgent Drupal announcements require your attention', 1);
+    $this->assertMailString('body', 'Critical Release - PSA-2019-02-19', 1);
+
+    // No email should be sent if PSA's are disabled.
+    $this->container->get('state')->set('system.test_mail_collector', []);
+    $this->container->get('state')->delete('automatic_updates.last_check');
+    $this->config('automatic_updates.settings')
+      ->set('enable_psa', FALSE)
+      ->save();
+    $notify->send();
+    $this->assertCount(0, $this->getMails());
+  }
+
+}