diff --git a/config/install/system.action.message_delete_action.yml b/config/install/system.action.message_delete_action.yml
new file mode 100644
index 0000000..9834d5f
--- /dev/null
+++ b/config/install/system.action.message_delete_action.yml
@@ -0,0 +1,10 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - contact
+id: message_delete_action
+label: 'Delete message'
+type: contact_message
+plugin: message_delete_action
+configuration: {  }
diff --git a/config/install/views.view.contact_messages.yml b/config/install/views.view.contact_messages.yml
index 8250ad1..f2b7499 100644
--- a/config/install/views.view.contact_messages.yml
+++ b/config/install/views.view.contact_messages.yml
@@ -84,6 +84,59 @@ display:
       row:
         type: 'entity:contact_message'
       fields:
+        message_bulk_form:
+          id: message_bulk_form
+          table: contact_message
+          field: message_bulk_form
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: ''
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: false
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          action_title: 'With selection'
+          include_exclude: exclude
+          selected_actions: {  }
+          entity_type: contact_message
+          plugin_id: message_bulk_form
         subject:
           id: subject
           table: contact_message
@@ -445,10 +498,14 @@ display:
       display_extenders: {  }
     cache_metadata:
       contexts:
-        0: user
-        2: cache.context.url
-        3: language
+        - 'languages:language_content'
+        - 'languages:language_interface'
+        - url
+        - url.query_args
+        - user.permissions
       cacheable: false
+      max-age: 0
+      tags: {  }
   page_1:
     display_plugin: page
     id: page_1
@@ -467,7 +524,11 @@ display:
       display_extenders: {  }
     cache_metadata:
       contexts:
-        0: user
-        2: cache.context.url
-        3: language
+        - 'languages:language_content'
+        - 'languages:language_interface'
+        - url
+        - url.query_args
+        - user.permissions
       cacheable: false
+      max-age: 0
+      tags: {  }
diff --git a/config/schema/contact_storage.schema.yml b/config/schema/contact_storage.schema.yml
index 92792ba..8f9c5c6 100644
--- a/config/schema/contact_storage.schema.yml
+++ b/config/schema/contact_storage.schema.yml
@@ -11,3 +11,7 @@ contact.form.*.third_party.contact_storage:
     show_preview:
       type: boolean
       label: 'Show preview button'
+
+action.configuration.message_delete_action:
+  type: action_configuration_default
+  label: 'Delete message configuration'
diff --git a/config/schema/contact_storage.views.schema.yml b/config/schema/contact_storage.views.schema.yml
index b000275..1ea1cce 100644
--- a/config/schema/contact_storage.views.schema.yml
+++ b/config/schema/contact_storage.views.schema.yml
@@ -1,3 +1,7 @@
 views.field.contact_form:
   type: views_field
   label: 'Contact form'
+
+views.field.message_bulk_form:
+  type: views_field_bulk_form
+  label: 'Contact Message bulk form'
diff --git a/contact_storage.post_update.php b/contact_storage.post_update.php
new file mode 100644
index 0000000..1949a59
--- /dev/null
+++ b/contact_storage.post_update.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * @file
+ * Post update functions for Contact Storage.
+ */
+
+use Drupal\system\Entity\Action;
+
+/**
+ * @addtogroup updates-8.x-1.0-beta4-to-8.x-1.0-beta5
+ * @{
+ */
+
+/**
+ * Enable the contact form delete multiple action
+ */
+function contact_storage_post_update_enable_action() {
+
+}
+
+/**
+ * @} End of "addtogroup updates-8.x-1.0-beta4-to-8.x-1.0-beta5".
+ */
diff --git a/contact_storage.routing.yml b/contact_storage.routing.yml
new file mode 100644
index 0000000..ee0f94f
--- /dev/null
+++ b/contact_storage.routing.yml
@@ -0,0 +1,6 @@
+entity.contact.multiple_delete_confirm:
+  path: '/admin/structure/contact/messages/delete'
+  defaults:
+    _form: '\Drupal\contact_storage\Form\DeleteMultiple'
+  requirements:
+    _permission: 'administer contact forms'
diff --git a/src/Form/DeleteMultiple.php b/src/Form/DeleteMultiple.php
new file mode 100644
index 0000000..255ade8
--- /dev/null
+++ b/src/Form/DeleteMultiple.php
@@ -0,0 +1,140 @@
+<?php
+
+namespace Drupal\contact_storage\Form;
+
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Form\ConfirmFormBase;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Url;
+use Drupal\user\PrivateTempStoreFactory;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\HttpFoundation\RedirectResponse;
+use Drupal\Core\Session\AccountInterface;
+use Drupal\Core\StringTranslation\TranslationInterface;
+
+/**
+ * Provides a message deletion confirmation form.
+ */
+class DeleteMultiple extends ConfirmFormBase {
+
+  /**
+   * The array of messages to delete.
+   *
+   * @var string[][]
+   */
+  protected $messages = array();
+
+  /**
+   * The tempstore factory.
+   *
+   * @var \Drupal\user\PrivateTempStoreFactory
+   */
+  protected $privateTempStoreFactory;
+
+  /**
+   * The message storage.
+   *
+   * @var \Drupal\Core\Entity\EntityStorageInterface
+   */
+  protected $storage;
+
+  /**
+   * The current user.
+   *
+   * @var \Drupal\Core\Session\AccountInterface
+   */
+  protected $account;
+
+  /**
+   * Constructs a DeleteMultiple form object.
+   *
+   * @param \Drupal\user\PrivateTempStoreFactory $temp_store_factory
+   *   The tempstore factory.
+   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
+   *   The entity type manager.
+   * @param \Drupal\Core\Session\AccountInterface $account
+   *   The current user.
+   */
+  public function __construct(PrivateTempStoreFactory $temp_store_factory, EntityTypeManagerInterface $entity_type_manager, AccountInterface $account, TranslationInterface $string_translation) {
+    $this->privateTempStoreFactory = $temp_store_factory;
+    $this->storage = $entity_type_manager->getStorage('contact_message');
+    $this->account = $account;
+    $this->stringTranslation = $string_translation;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    return new static(
+      $container->get('user.private_tempstore'),
+      $container->get('entity_type.manager'),
+      $container->get('current_user'),
+      $container->get('string_translation')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormId() {
+    return 'message_multiple_delete_confirm';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getQuestion() {
+    return $this->formatPlural(count($this->messages), 'Are you sure you want to delete this item?', 'Are you sure you want to delete these items?');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCancelUrl() {
+    return new Url('entity.contact_message.collection');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getConfirmText() {
+    return t('Delete');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildForm(array $form, FormStateInterface $form_state) {
+    $this->messages = $this->privateTempStoreFactory->get('message_multiple_delete_confirm')->get(\Drupal::currentUser()->id());
+    if (empty($this->messages)) {
+      return new RedirectResponse($this->getCancelUrl()->setAbsolute()->toString());
+    }
+
+    $form['messages'] = [
+      '#theme' => 'item_list',
+      '#items' => array_map(function ($message) {
+        return $message->label();
+      }, $this->messages),
+    ];
+    $form = parent::buildForm($form, $form_state);
+
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, FormStateInterface $form_state) {
+
+    if ($form_state->getValue('confirm') && !empty($this->messages)) {
+      $this->storage->delete($this->messages);
+      $this->privateTempStoreFactory->get('message_multiple_delete_confirm')->delete($this->account->id());
+      $count = count($this->messages);
+      $this->logger('content')->notice('Deleted @count messages.', ['@count' => $count]);
+      drupal_set_message($this->stringTranslation->formatPlural($count, 'Deleted 1 message.', 'Deleted @count messages.'));
+    }
+    $form_state->setRedirect('entity.contact_message.collection');
+  }
+
+}
diff --git a/src/MessageViewsData.php b/src/MessageViewsData.php
index 3af8031..6ff6503 100644
--- a/src/MessageViewsData.php
+++ b/src/MessageViewsData.php
@@ -28,6 +28,14 @@ class MessageViewsData extends EntityViewsData {
       ),
     );
 
+    $data['contact_message']['message_bulk_form'] = array(
+      'title' => $this->t('Message operations bulk form'),
+      'help' => $this->t('Add a form element that lets you run operations on multiple messages.'),
+      'field' => array(
+        'id' => 'message_bulk_form',
+      ),
+    );
+
     return $data;
   }
 
diff --git a/src/Plugin/Action/DeleteMessage.php b/src/Plugin/Action/DeleteMessage.php
new file mode 100644
index 0000000..5498fb3
--- /dev/null
+++ b/src/Plugin/Action/DeleteMessage.php
@@ -0,0 +1,93 @@
+<?php
+
+namespace Drupal\contact_storage\Plugin\Action;
+
+use Drupal\Core\Action\ActionBase;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Drupal\Core\Session\AccountInterface;
+use Drupal\user\PrivateTempStoreFactory;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Redirects to a message deletion form.
+ *
+ * @Action(
+ *   id = "message_delete_action",
+ *   label = @Translation("Delete message"),
+ *   type = "contact_message",
+ *   confirm_form_route_name = "entity.contact.multiple_delete_confirm"
+ * )
+ */
+class DeleteMessage extends ActionBase implements ContainerFactoryPluginInterface {
+
+  /**
+   * The tempstore object.
+   *
+   * @var \Drupal\user\SharedTempStore
+   */
+  protected $privateTempStore;
+
+  /**
+   * The current user.
+   *
+   * @var \Drupal\Core\Session\AccountInterface
+   */
+  protected $currentUser;
+
+  /**
+   * Constructs a new DeleteMessage 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 mixed $plugin_definition
+   *   The plugin implementation definition.
+   * @param \Drupal\user\PrivateTempStoreFactory $temp_store_factory
+   *   The tempstore factory.
+   * @param AccountInterface $current_user
+   *   Current user.
+   */
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, PrivateTempStoreFactory $temp_store_factory, AccountInterface $current_user) {
+    $this->currentUser = $current_user;
+    $this->privateTempStore = $temp_store_factory->get('message_multiple_delete_confirm');
+
+    parent::__construct($configuration, $plugin_id, $plugin_definition);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('user.private_tempstore'),
+      $container->get('current_user')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function executeMultiple(array $entities) {
+    $this->privateTempStore->set($this->currentUser->id(), $entities);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function execute($object = NULL) {
+    $this->executeMultiple(array($object));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) {
+    /** @var \Drupal\contact\MessageInterface $object */
+    return $object->access('delete', $account, $return_as_object);
+  }
+
+}
diff --git a/src/Plugin/views/field/MessageBulkForm.php b/src/Plugin/views/field/MessageBulkForm.php
new file mode 100644
index 0000000..4afee92
--- /dev/null
+++ b/src/Plugin/views/field/MessageBulkForm.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace Drupal\contact_storage\Plugin\views\field;
+
+use Drupal\system\Plugin\views\field\BulkForm;
+
+/**
+ * Defines a contact message operations bulk form element.
+ *
+ * @ViewsField("message_bulk_form")
+ */
+class MessageBulkForm extends BulkForm {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function emptySelectedMessage() {
+    return $this->t('No message selected.');
+  }
+
+}
diff --git a/src/Tests/BulkFormTest.php b/src/Tests/BulkFormTest.php
new file mode 100644
index 0000000..a7095be
--- /dev/null
+++ b/src/Tests/BulkFormTest.php
@@ -0,0 +1,76 @@
+<?php
+
+namespace Drupal\contact_storage\Tests;
+
+use Drupal\Component\Utility\SafeMarkup;
+use Drupal\views\Tests\ViewTestData;
+
+/**
+ * Tests a contact message bulk form.
+ *
+ * @group contact_storage
+ * @see \Drupal\contact_storage\Plugin\views\field\MessageBulkForm
+ */
+class BulkFormTest extends ContactStorageTestBase {
+
+  /**
+   * Modules to be enabled.
+   *
+   * @var array
+   */
+  public static $modules = array(
+    'contact',
+    'contact_test_views',
+    'contact_storage',
+    'views',
+    'language',
+  );
+
+  /**
+   * Views used by this test.
+   *
+   * @var array
+   */
+  public static $testViews = array('test_contact_message_bulk_form');
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::Setup();
+    // Create and login administrative user.
+    $admin_user = $this->drupalCreateUser(array(
+      'administer contact forms',
+    ));
+    $this->drupalLogin($admin_user);
+    // Create first valid contact form.
+    $mail = 'simpletest@example.com';
+    $this->addContactForm('test_id', 'test_label', $mail, '', TRUE);
+    $this->assertText(t('Contact form test_label has been added.'));
+    $this->drupalLogout();
+
+    // Ensure that anonymous can submit site-wide contact form.
+    user_role_grant_permissions(DRUPAL_ANONYMOUS_RID, array('access site-wide contact form'));
+    $this->drupalGet('contact');
+    $this->assertText(t('Your email address'));
+    // Submit contact form few times.
+    for ($i = 1; $i <= 5; $i++) {
+      $this->submitContact($this->randomMachineName(), $mail, $this->randomMachineName(), 'test_id', $this->randomMachineName());
+      $this->assertText(t('Your message has been sent.'));
+    }
+  }
+
+  /**
+   * Test multiple deletion.
+   */
+  public function testBulkDeletion() {
+    $this->drupalGet('contact');
+    ViewTestData::createTestViews(get_class($this), array('contact_test_views'));
+    // Check the operations are accessible to the administer permission user.
+    $this->drupalLogin($this->drupalCreateUser(array('administer contact forms')));
+    $this->drupalGet('test-contact-message-bulk-form');
+    $elements = $this->xpath('//select[@id="edit-action"]//option');
+    $this->assertIdentical(count($elements), 8, 'All contact message operations are found.');
+  }
+
+}
diff --git a/tests/modules/contact_test_views/contact_test_views.info.yml b/tests/modules/contact_test_views/contact_test_views.info.yml
new file mode 100644
index 0000000..3157e2d
--- /dev/null
+++ b/tests/modules/contact_test_views/contact_test_views.info.yml
@@ -0,0 +1,11 @@
+name: 'Contact test views'
+type: module
+description: 'Provides default views for views contact tests.'
+package: Testing
+version: VERSION
+core: 8.x
+dependencies:
+  - contact
+  - contact_storage
+  - views
+  - language
diff --git a/tests/modules/contact_test_views/test_views/views.view.test_contact_message_bulk_form.yml b/tests/modules/contact_test_views/test_views/views.view.test_contact_message_bulk_form.yml
new file mode 100644
index 0000000..fd7f0f3
--- /dev/null
+++ b/tests/modules/contact_test_views/test_views/views.view.test_contact_message_bulk_form.yml
@@ -0,0 +1,188 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - contact
+    - contact_storage
+id: test_contact_message_bulk_form
+label: ''
+module: views
+description: ''
+tag: ''
+base_table: contact_message
+base_field: id
+core: 8.x
+display:
+  default:
+    display_plugin: default
+    id: default
+    display_title: Master
+    position: null
+    display_options:
+      style:
+        type: table
+      row:
+        type: fields
+      fields:
+        message_bulk_form:
+          id: message_bulk_form
+          table: contact_message
+          field: message_bulk_form
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: 'Message operations bulk form'
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          action_title: 'With selection'
+          include_exclude: exclude
+          selected_actions: {  }
+          entity_type: contact_message
+          plugin_id: message_bulk_form
+        subject:
+          table: contact_message
+          field: subject
+          id: subject
+          entity_type: null
+          entity_field: subject
+          plugin_id: field
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: Subject
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          click_sort_column: value
+          type: string
+          settings: {  }
+          group_column: value
+          group_columns: {  }
+          group_rows: true
+          delta_limit: 0
+          delta_offset: 0
+          delta_reversed: false
+          delta_first_last: false
+          multi_type: separator
+          separator: ', '
+          field_api_classes: false
+      filters: {  }
+      sorts:
+        id:
+          id: id
+          table: contact_message
+          field: id
+          relationship: none
+          group_type: group
+          admin_label: ''
+          order: ASC
+          exposed: false
+          expose:
+            label: ''
+          entity_type: contact_message
+          entity_field: id
+          plugin_id: standard
+      title: ''
+      header: {  }
+      footer: {  }
+      empty: {  }
+      relationships: {  }
+      arguments: {  }
+      display_extenders: {  }
+    cache_metadata:
+      max-age: 0
+      contexts:
+        - 'languages:language_content'
+        - 'languages:language_interface'
+        - url.query_args
+      tags: {  }
+  page_1:
+    display_plugin: page
+    id: page_1
+    display_title: Page
+    position: 1
+    display_options:
+      display_extenders: {  }
+      path: test-contact-message-bulk-form
+    cache_metadata:
+      max-age: 0
+      contexts:
+        - 'languages:language_content'
+        - 'languages:language_interface'
+        - url.query_args
+      tags: {  }
