diff --git a/app/assets/javascripts/discourse/controllers/discovery_topics_controller.js b/app/assets/javascripts/discourse/controllers/discovery_topics_controller.js
index 47d1c1049..1e9211841 100644
--- a/app/assets/javascripts/discourse/controllers/discovery_topics_controller.js
+++ b/app/assets/javascripts/discourse/controllers/discovery_topics_controller.js
@@ -28,6 +28,12 @@ Discourse.DiscoveryTopicsController = Discourse.DiscoveryController.extend({
       this.send('loading');
       Discourse.TopicList.find(filter).then(function(list) {
         self.setProperties({ model: list, selected: [] });
+
+        var tracking = Discourse.TopicTrackingState.current();
+        if (tracking) {
+          tracking.sync(list, filter);
+        }
+
         self.send('loadingComplete');
       });
     },
@@ -43,12 +49,13 @@ Discourse.DiscoveryTopicsController = Discourse.DiscoveryController.extend({
           operation = { type: 'change_notification_level',
                         notification_level: Discourse.Topic.NotificationLevel.REGULAR };
 
+      var promise;
       if (selected.length > 0) {
-        Discourse.Topic.bulkOperation(selected, operation).then(function() {
-          self.send('refresh');
-        });
+        promise = Discourse.Topic.bulkOperation(selected, operation);
       } else {
+        promise = Discourse.Topic.bulkOperationByFilter(this.get('filter'), operation);
       }
+      promise.then(function() { self.send('refresh'); });
     }
   },
 
diff --git a/app/assets/javascripts/discourse/models/topic.js b/app/assets/javascripts/discourse/models/topic.js
index dbbc5d16f..9a32ada28 100644
--- a/app/assets/javascripts/discourse/models/topic.js
+++ b/app/assets/javascripts/discourse/models/topic.js
@@ -420,6 +420,13 @@ Discourse.Topic.reopenClass({
         operation: operation
       }
     });
+  },
+
+  bulkOperationByFilter: function(filter, operation) {
+    return Discourse.ajax("/topics/bulk", {
+      type: 'PUT',
+      data: { filter: filter, operation: operation }
+    });
   }
 
 });
diff --git a/app/controllers/topics_controller.rb b/app/controllers/topics_controller.rb
index 3d76a50e7..cbb9011cb 100644
--- a/app/controllers/topics_controller.rb
+++ b/app/controllers/topics_controller.rb
@@ -265,7 +265,15 @@ class TopicsController < ApplicationController
   end
 
   def bulk
-    topic_ids = params.require(:topic_ids).map {|t| t.to_i}
+    if params[:topic_ids].present?
+      topic_ids = params[:topic_ids].map {|t| t.to_i}
+    elsif params[:filter] == 'unread'
+      tq = TopicQuery.new(current_user)
+      topic_ids = TopicQuery.unread_filter(tq.joined_topic_user).listable_topics.pluck(:id)
+    else
+      raise ActionController::ParameterMissing.new(:topic_ids)
+    end
+
     operation = params.require(:operation).symbolize_keys
     raise ActionController::ParameterMissing.new(:operation_type) if operation[:type].blank?
     operator = TopicsBulkAction.new(current_user, topic_ids, operation)
diff --git a/lib/topic_query.rb b/lib/topic_query.rb
index b0e4d5452..849dc7e75 100644
--- a/lib/topic_query.rb
+++ b/lib/topic_query.rb
@@ -38,6 +38,10 @@ class TopicQuery
     @user = user
   end
 
+  def joined_topic_user(list=nil)
+    (list || Topic).joins("LEFT OUTER JOIN topic_users AS tu ON (topics.id = tu.topic_id AND tu.user_id = #{@user.id.to_i})")
+  end
+
   # Return a list of suggested topics for a topic
   def list_suggested_for(topic)
     builder = SuggestedTopicsBuilder.new(topic)
@@ -209,6 +213,7 @@ class TopicQuery
       result.order("topics.#{sort_column} #{sort_dir}")
     end
 
+
     # Create results based on a bunch of default options
     def default_results(options={})
       options.reverse_merge!(@options)
diff --git a/spec/controllers/topics_controller_spec.rb b/spec/controllers/topics_controller_spec.rb
index 51006b533..6de216c2c 100644
--- a/spec/controllers/topics_controller_spec.rb
+++ b/spec/controllers/topics_controller_spec.rb
@@ -791,7 +791,7 @@ describe TopicsController do
       let(:operation) { {type: 'change_category', category_id: '1'} }
       let(:topic_ids) { [1,2,3] }
 
-      it "requires a list of topic_ids" do
+      it "requires a list of topic_ids or filter" do
         lambda { xhr :put, :bulk, operation: operation }.should raise_error(ActionController::ParameterMissing)
       end