diff --git a/CHANGELOG b/CHANGELOG
index f6d39b28c3bcc866d8e15883a81104a262d6c827..d8ef5866a1a1ae5af3435ae010e3a4659ebbe2bf 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -120,6 +120,7 @@ v 8.10.0 (unreleased)
   - Limit the number of retries on error to 3 for exporting projects
   - Allow empty repositories on project import/export
   - Render only commit message title in builds (Katarzyna Kobierska Ula Budziszewska)
+  - Allow bulk (un)subscription from issues in issue index
 
 v 8.9.6
   - Fix importing of events under notes for GitLab projects. !5154
diff --git a/app/assets/javascripts/issues-bulk-assignment.js.coffee b/app/assets/javascripts/issues-bulk-assignment.js.coffee
index 6b0e69dbae7a5e52cbd9c8ce5f93b357b4e17845..3d09ea08e3b1833d8813fd12c18811db7636286d 100644
--- a/app/assets/javascripts/issues-bulk-assignment.js.coffee
+++ b/app/assets/javascripts/issues-bulk-assignment.js.coffee
@@ -85,12 +85,13 @@ class @IssuableBulkActions
   getFormDataAsObject: ->
     formData =
       update:
-        state_event       : @form.find('input[name="update[state_event]"]').val()
-        assignee_id       : @form.find('input[name="update[assignee_id]"]').val()
-        milestone_id      : @form.find('input[name="update[milestone_id]"]').val()
-        issues_ids        : @form.find('input[name="update[issues_ids]"]').val()
-        add_label_ids     : []
-        remove_label_ids  : []
+        state_event        : @form.find('input[name="update[state_event]"]').val()
+        assignee_id        : @form.find('input[name="update[assignee_id]"]').val()
+        milestone_id       : @form.find('input[name="update[milestone_id]"]').val()
+        issues_ids         : @form.find('input[name="update[issues_ids]"]').val()
+        subscription_event : @form.find('input[name="update[subscription_event]"]').val()
+        add_label_ids      : []
+        remove_label_ids   : []
 
     if @willUpdateLabels
       @getLabelsToApply().map (id) ->
diff --git a/app/assets/javascripts/subscription_select.js.coffee b/app/assets/javascripts/subscription_select.js.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..e5eb7a50d803351557579aade6834be2badde712
--- /dev/null
+++ b/app/assets/javascripts/subscription_select.js.coffee
@@ -0,0 +1,18 @@
+class @SubscriptionSelect
+  constructor: ->
+    $('.js-subscription-event').each (i, el) ->
+      fieldName = $(el).data("field-name")
+
+      $(el).glDropdown(
+        selectable: true
+        fieldName: fieldName
+        toggleLabel: (selected, el, instance) =>
+          label = 'Subscription'
+          $item = instance.dropdown.find('.is-active')
+          label = $item.text() if $item.length
+          label
+        clicked: (item, $el, e)->
+          e.preventDefault()
+        id: (obj, el) ->
+          $(el).data("id")
+      )
diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb
index b6e80762e3c5a00637c60af3957d856c34861d76..fa663c9bda4f0e24ca5133bdbca33a1cbe7ae395 100644
--- a/app/controllers/projects/issues_controller.rb
+++ b/app/controllers/projects/issues_controller.rb
@@ -226,6 +226,7 @@ class Projects::IssuesController < Projects::ApplicationController
       :assignee_id,
       :milestone_id,
       :state_event,
+      :subscription_event,
       label_ids: [],
       add_label_ids: [],
       remove_label_ids: []
diff --git a/app/services/issuable_base_service.rb b/app/services/issuable_base_service.rb
index e3dc569152cda3af69f5719f6a94fffa0461095a..2d96efe1042c955fc984e0c895ae6ae9e84a6100 100644
--- a/app/services/issuable_base_service.rb
+++ b/app/services/issuable_base_service.rb
@@ -101,6 +101,7 @@ class IssuableBaseService < BaseService
 
   def update(issuable)
     change_state(issuable)
+    change_subscription(issuable)
     filter_params
     old_labels = issuable.labels.to_a
 
@@ -124,6 +125,15 @@ class IssuableBaseService < BaseService
     end
   end
 
+  def change_subscription(issuable)
+    case params.delete(:subscription_event)
+    when 'subscribe'
+      issuable.subscribe(current_user)
+    when 'unsubscribe'
+      issuable.unsubscribe(current_user)
+    end
+  end
+
   def has_changes?(issuable, old_labels: [])
     valid_attrs = [:title, :description, :assignee_id, :milestone_id, :target_branch]
 
diff --git a/app/services/issues/bulk_update_service.rb b/app/services/issues/bulk_update_service.rb
index cd08c3a0cb97aff548f4e4b634809d247f3b008e..7e19a73f71a22491f18dff6be77ba9698ce03641 100644
--- a/app/services/issues/bulk_update_service.rb
+++ b/app/services/issues/bulk_update_service.rb
@@ -4,7 +4,7 @@ module Issues
       issues_ids   = params.delete(:issues_ids).split(",")
       issue_params = params
 
-      %i(state_event milestone_id assignee_id add_label_ids remove_label_ids).each do |key|
+      %i(state_event milestone_id assignee_id add_label_ids remove_label_ids subscription_event).each do |key|
         issue_params.delete(key) unless issue_params[key].present?
       end
 
diff --git a/app/views/shared/issuable/_filter.html.haml b/app/views/shared/issuable/_filter.html.haml
index 094d6636c665e91c4d87b12b5293d89eb0b48090..0b7fa8c7d06d34a5cd7aa36683aedd4aae4d6248 100644
--- a/app/views/shared/issuable/_filter.html.haml
+++ b/app/views/shared/issuable/_filter.html.haml
@@ -44,9 +44,15 @@
               placeholder: "Search authors", data: { first_user: (current_user.username if current_user), null_user: true, current_user: true, project_id: @project.id, field_name: "update[assignee_id]" } })
           .filter-item.inline
             = dropdown_tag("Milestone", options: { title: "Assign milestone", toggle_class: 'js-milestone-select js-extra-options js-filter-submit js-filter-bulk-update', filter: true, dropdown_class: "dropdown-menu-selectable dropdown-menu-milestone", placeholder: "Search milestones", data: { show_no: true, field_name: "update[milestone_id]", project_id: @project.id, milestones: namespace_project_milestones_path(@project.namespace, @project, :json), use_id: true } })
-
           .filter-item.inline.labels-filter
             = render "shared/issuable/label_dropdown", classes: ['js-filter-bulk-update', 'js-multiselect'], show_create: false, show_footer: false, extra_options: false, filter_submit: false, show_footer: false, data_options: { persist_when_hide: "true", field_name: "update[label_ids][]", show_no: false, show_any: false, use_id: true }
+          .filter-item.inline
+            = dropdown_tag("Subscription", options: { toggle_class: "js-subscription-event", title: "Change subscription", dropdown_class: "dropdown-menu-selectable", data: { field_name: "update[subscription_event]" } } ) do
+              %ul
+                %li
+                  %a{href: "#", data: {id: "subscribe"}} Subscribe
+                %li
+                  %a{href: "#", data: {id: "unsubscribe"}} Unsubscribe
 
           = hidden_field_tag 'update[issues_ids]', []
           = hidden_field_tag :state_event, params[:state_event]
@@ -63,6 +69,7 @@
   new LabelsSelect();
   new MilestoneSelect();
   new IssueStatusSelect();
+  new SubscriptionSelect();
   $('form.filter-form').on('submit', function (event) {
     event.preventDefault();
     Turbolinks.visit(this.action + '&' + $(this).serialize());
diff --git a/spec/services/issues/bulk_update_service_spec.rb b/spec/services/issues/bulk_update_service_spec.rb
index 4a689e64dc5d0641bcb0accd71381b2b050e5e9f..ba3a4dfc048fd742fa9aedd324130a53c790fdfe 100644
--- a/spec/services/issues/bulk_update_service_spec.rb
+++ b/spec/services/issues/bulk_update_service_spec.rb
@@ -262,4 +262,42 @@ describe Issues::BulkUpdateService, services: true do
       end
     end
   end
+
+  describe :subscribe_issues do
+    let(:issues) { create_list(:issue, 5, project: project) }
+    let(:params) do
+      {
+        subscription_event: 'subscribe',
+        issues_ids: issues.map(&:id).join(',')
+      }
+    end
+
+    it 'subscribes the given user' do
+      issues.each do |issue|
+        expect(issue.subscribed?(user)).to be_truthy
+      end
+    end
+  end
+
+  describe :unsubscribe_issues do
+    let(:issues) { create_list(:closed_issue, 5, project: project) }
+    let(:params) do
+      {
+        subscription_event: 'unsubscribe',
+        issues_ids: issues.map(&:id).join(',')
+      }
+    end
+
+    before do
+      issues.each do |issue|
+        issue.subscriptions.create(user: user, subscribed: true)
+      end
+    end
+
+    it 'unsubscribes the given user' do
+      issues.each do |issue|
+        expect(issue.subscribed?(user)).to be_falsey
+      end
+    end
+  end
 end