diff --git a/src/Plugin/inmail/Deliverer/FetcherBase.php b/src/Plugin/inmail/Deliverer/FetcherBase.php
index 0731835..ec857c0 100644
--- a/src/Plugin/inmail/Deliverer/FetcherBase.php
+++ b/src/Plugin/inmail/Deliverer/FetcherBase.php
@@ -111,4 +111,34 @@ abstract class FetcherBase extends DelivererBase implements FetcherInterface {
     $this->setCount(NULL);
   }
 
+  /**
+   * Handles submit call of "Connect" button.
+   */
+  public function submitConnect(array $form, FormStateInterface $form_state) {
+    // Implement in the subclass.
+  }
+
+  /**
+   * Adds a "Connect" button to a form.
+   *
+   * @return array
+   *   A form array containing "Connect" button.
+   */
+  public function addConnectButton() {
+    $form['connect'] = array(
+      '#type' => 'submit',
+      '#value' => t('Connect'),
+      '#submit' => array(
+        array($this, 'submitConnect'),
+      ),
+      '#executes_submit_callback' => TRUE,
+      '#ajax' => array(
+        'callback' => '::getPluginContainerFormChild',
+        'wrapper' => 'inmail-plugin',
+      ),
+    );
+
+    return $form;
+  }
+
 }
diff --git a/src/Plugin/inmail/Deliverer/ImapFetcher.php b/src/Plugin/inmail/Deliverer/ImapFetcher.php
index 71dc8c3..2266ead 100644
--- a/src/Plugin/inmail/Deliverer/ImapFetcher.php
+++ b/src/Plugin/inmail/Deliverer/ImapFetcher.php
@@ -145,31 +145,34 @@ class ImapFetcher extends FetcherBase implements ContainerFactoryPluginInterface
    * {@inheritdoc}
    */
   public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
-    $form['info'] = array(
+    $form['imap'] = array(
+      '#type' => 'fieldset',
+      '#title' => $this->t('IMAP'),
+    );
+    $form['imap']['info'] = array(
       '#type' => 'item',
       '#markup' => $this->t('Please refer to your email provider for the appropriate values for these fields.'),
     );
-
-    $form['host'] = array(
+    $form['imap']['host'] = array(
       '#type' => 'textfield',
       '#title' => $this->t('Host'),
       '#default_value' => $this->configuration['host'],
     );
 
-    $form['port'] = array(
+    $form['imap']['port'] = array(
       '#type' => 'number',
       '#title' => $this->t('Port'),
       '#default_value' => $this->configuration['port'],
       '#description' => $this->t('The standard port number is 143, or 993 when using SSL.'),
     );
 
-    $form['ssl'] = array(
+    $form['imap']['ssl'] = array(
       '#type' => 'checkbox',
       '#title' => $this->t('Use SSL'),
       '#default_value' => $this->configuration['ssl'],
     );
 
-    $form['username'] = array(
+    $form['imap']['username'] = array(
       '#type' => 'textfield',
       '#title' => $this->t('Username'),
       '#default_value' => $this->configuration['username'],
@@ -178,12 +181,12 @@ class ImapFetcher extends FetcherBase implements ContainerFactoryPluginInterface
     // Password field cannot have #default_value. To avoid forcing user to
     // re-enter password with each save, password updating is conditional on
     // this checkbox.
-    $form['password_update'] = array(
+    $form['imap']['password_update'] = array(
       '#type' => 'checkbox',
       '#title' => $this->t('Update password'),
     );
 
-    $form['password'] = array(
+    $form['imap']['password'] = array(
       '#type' => 'password',
       '#title' => $this->t('Password'),
       '#states' => array(
@@ -195,8 +198,8 @@ class ImapFetcher extends FetcherBase implements ContainerFactoryPluginInterface
 
     // Always show password field if configuration is new.
     if ($form_state->getFormObject()->getEntity()->isNew()) {
-      $form['password_update']['#access'] = FALSE;
-      $form['password']['#states']['visible'] = array();
+      $form['imap']['password_update']['#access'] = FALSE;
+      $form['imap']['password']['#states']['visible'] = array();
     }
 
     $form['batch_size'] = array(
@@ -206,15 +209,19 @@ class ImapFetcher extends FetcherBase implements ContainerFactoryPluginInterface
       '#description' => $this->t('How many messages to fetch on each invocation.'),
     );
 
+    // Add a "Connect" button.
+    $form['imap'] += parent::addConnectButton();
+
     return $form;
   }
 
   /**
-   * {@inheritdoc}
+   * Updates the fetcher configuration.
+   *
+   * @param \Drupal\Core\Form\FormStateInterface $form_state
+   *   The form state.
    */
-  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
-    parent::submitConfigurationForm($form, $form_state);
-
+  protected function updateConfiguration(FormStateInterface $form_state) {
     $configuration = array(
       'host' => $form_state->getValue('host'),
       'port' => $form_state->getValue('port'),
@@ -231,4 +238,27 @@ class ImapFetcher extends FetcherBase implements ContainerFactoryPluginInterface
     $this->setConfiguration($configuration);
   }
 
+  /**
+   * Handles submit call of "Connect" button.
+   */
+  public function submitConnect(array $form, FormStateInterface $form_state) {
+    $this->updateConfiguration($form_state);
+    $status = $this->doImap(function ($imap_stream) {
+      drupal_set_message(t('Successfully connected!'));
+      return TRUE;
+    });
+    if (!$status) {
+      drupal_set_message(t('Invalid credentials!'), 'warning');
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
+    parent::submitConfigurationForm($form, $form_state);
+
+    $this->updateConfiguration($form_state);
+  }
+
 }
diff --git a/src/Tests/InmailWebTest.php b/src/Tests/InmailWebTest.php
index 18619b1..84e4659 100644
--- a/src/Tests/InmailWebTest.php
+++ b/src/Tests/InmailWebTest.php
@@ -90,6 +90,8 @@ class InmailWebTest extends WebTestBase {
       'plugin' => 'imap',
     );
     $this->drupalPostAjaxForm(NULL, $edit, 'plugin');
+    $this->assertText('IMAP');
+    $this->assertRaw('<input data-drupal-selector="edit-connect" type="submit"');
     $edit += array(
       'host' => 'imap.example.com',
       'username' => 'user',
