diff --git a/CHANGELOG b/CHANGELOG
index 9cfa04b1e631addc7f4fc66aeed782b9169a9b4a..b876e0271323c4817b0a4a53185b067f5ba7931a 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -267,6 +267,7 @@ v 8.5.7
 
 v 8.5.6
   - Obtain a lease before querying LDAP
+  - Add ability set due date to issues, sort and filter issues by due date
 
 v 8.5.5
   - Ensure removing a project removes associated Todo entries
diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb
index e86428147ef0521cc35466277647b135eb3c41c5..b96ab91c17db96aa00c8c746a93238341ba1378b 100644
--- a/app/controllers/projects/issues_controller.rb
+++ b/app/controllers/projects/issues_controller.rb
@@ -192,7 +192,7 @@ class Projects::IssuesController < Projects::ApplicationController
   def issue_params
     params.require(:issue).permit(
       :title, :assignee_id, :position, :description, :confidential,
-      :milestone_id, :state_event, :task_num, label_ids: []
+      :milestone_id, :due_date, :state_event, :task_num, label_ids: []
     )
   end
 
diff --git a/app/finders/issuable_finder.rb b/app/finders/issuable_finder.rb
index 5eb1d3f5aac7fc547d58fafae8b941f78539550f..5e08193b5cfc374f6175a36d5c142e4212614b78 100644
--- a/app/finders/issuable_finder.rb
+++ b/app/finders/issuable_finder.rb
@@ -39,6 +39,7 @@ class IssuableFinder
     items = by_assignee(items)
     items = by_author(items)
     items = by_label(items)
+    items = by_due_date(items)
     sort(items)
   end
 
@@ -112,6 +113,14 @@ class IssuableFinder
       end
   end
 
+  def due_date?
+    params[:due_date].present?
+  end
+
+  def filter_by_no_due_date?
+    due_date? && params[:due_date] == Issue::NO_DUE_DATE[1]
+  end
+
   def labels?
     params[:label_name].present?
   end
@@ -283,6 +292,19 @@ class IssuableFinder
     items.distinct
   end
 
+  def by_due_date(items)
+    if due_date?
+      if filter_by_no_due_date?
+        items = items.no_due_date
+      else
+        items = items.has_due_date
+        # Must use issues prefix to avoid ambiguous match with Milestone#due_date
+        items = items.where("issues.due_date > ? AND issues.due_date <= ?", Date.today, params[:due_date])
+      end
+    end
+    items
+  end
+
   def label_names
     params[:label_name].split(',')
   end
diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb
index 4cb8adcebad4ae6010cb7a5c323074b3728a2ffe..2a193e12ec96c304af252a405b0016ec93266edd 100644
--- a/app/helpers/issues_helper.rb
+++ b/app/helpers/issues_helper.rb
@@ -172,6 +172,17 @@ module IssuesHelper
     end.to_h
   end
 
+  def due_date_options
+    options = [
+      ["Due to tomorrow", 1.day.from_now.to_date],
+      ["Due in this week", 1.week.from_now.to_date]
+    ]
+    options.unshift(Issue::ANY_DUE_DATE)
+    options.unshift(Issue::NO_DUE_DATE)
+    options_for_select(options, params[:due_date])
+  end
+
+
   # Required for Banzai::Filter::IssueReferenceFilter
   module_function :url_for_issue
 end
diff --git a/app/helpers/sorting_helper.rb b/app/helpers/sorting_helper.rb
index 2f2d2721d6df0f775c6287dd0917f05ef08f7680..624cb7bb8475a3b7a804a6fb6cc2802e9945cf48 100644
--- a/app/helpers/sorting_helper.rb
+++ b/app/helpers/sorting_helper.rb
@@ -8,6 +8,8 @@ module SortingHelper
       sort_value_oldest_created => sort_title_oldest_created,
       sort_value_milestone_soon => sort_title_milestone_soon,
       sort_value_milestone_later => sort_title_milestone_later,
+      sort_value_due_date_soon => sort_title_due_date_soon,
+      sort_value_due_date_later => sort_title_due_date_later,
       sort_value_largest_repo => sort_title_largest_repo,
       sort_value_recently_signin => sort_title_recently_signin,
       sort_value_oldest_signin => sort_title_oldest_signin,
@@ -50,6 +52,14 @@ module SortingHelper
     'Milestone due later'
   end
 
+  def sort_title_due_date_soon
+    'Due date soon'
+  end
+
+  def sort_title_due_date_later
+    'Due date due later'
+  end
+
   def sort_title_name
     'Name'
   end
@@ -98,6 +108,14 @@ module SortingHelper
     'milestone_due_desc'
   end
 
+  def sort_value_due_date_soon
+    'due_date_asc'
+  end
+
+  def sort_value_due_date_later
+    'due_date_desc'
+  end
+
   def sort_value_name
     'name_asc'
   end
diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb
index afa2ca039aef1cccfb97265a92c706d26199760d..691b7e104e4681f5b2ab52701a894872c1bf1509 100644
--- a/app/models/concerns/issuable.rb
+++ b/app/models/concerns/issuable.rb
@@ -39,6 +39,8 @@ module Issuable
     scope :order_milestone_due_asc, -> { joins(:milestone).reorder('milestones.due_date ASC, milestones.id ASC') }
     scope :with_label, ->(title) { joins(:labels).where(labels: { title: title }) }
     scope :without_label, -> { joins("LEFT OUTER JOIN label_links ON label_links.target_type = '#{name}' AND label_links.target_id = #{table_name}.id").where(label_links: { id: nil }) }
+    scope :has_due_date, ->{ where("issues.due_date IS NOT NULL") }
+    scope :no_due_date, ->{ where("issues.due_date IS NULL")}
 
     scope :join_project, -> { joins(:project) }
     scope :references_project, -> { references(:project) }
diff --git a/app/models/concerns/sortable.rb b/app/models/concerns/sortable.rb
index 8b47b9e0abd2879d2b67275b90e8e3c78c81849a..c88a8f5ceb885b8cdaf7710c7536019b3e7c3413 100644
--- a/app/models/concerns/sortable.rb
+++ b/app/models/concerns/sortable.rb
@@ -18,6 +18,8 @@ module Sortable
     scope :order_updated_asc, -> { reorder(updated_at: :asc) }
     scope :order_name_asc, -> { reorder(name: :asc) }
     scope :order_name_desc, -> { reorder(name: :desc) }
+    scope :due_date_asc, -> { reorder(due_date: :asc) }
+    scope :due_date_desc, -> { reorder("due_date IS NULL, due_date DESC") }
   end
 
   module ClassMethods
@@ -31,6 +33,8 @@ module Sortable
       when 'created_desc' then order_created_desc
       when 'id_desc' then order_id_desc
       when 'id_asc' then order_id_asc
+      when 'due_date_asc' then due_date_asc
+      when 'due_date_desc' then due_date_desc
       else
         all
       end
diff --git a/app/models/issue.rb b/app/models/issue.rb
index a009e235b37a1087ddf6a41265940c6f808a72d0..ee5be904330c636c7d2dfa1b8180006ae8ba8da3 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -28,6 +28,9 @@ class Issue < ActiveRecord::Base
   include Sortable
   include Taskable
 
+  NO_DUE_DATE = ['No Due Date', '0']
+  ANY_DUE_DATE = ['Any Due Date', '']
+
   ActsAsTaggableOn.strict_case_match = true
 
   belongs_to :project
diff --git a/app/views/projects/issues/_issue.html.haml b/app/views/projects/issues/_issue.html.haml
index 7a8009f6da49727887fea4110de2b0d416bda971..c4feb6d3e18d628ff90a54c29d635e3c1da8e0a8 100644
--- a/app/views/projects/issues/_issue.html.haml
+++ b/app/views/projects/issues/_issue.html.haml
@@ -48,6 +48,10 @@
       = link_to namespace_project_issues_path(issue.project.namespace, issue.project, milestone_title: issue.milestone.title) do
         = icon('clock-o')
         = issue.milestone.title
+    - if issue.due_date
+      &nbsp;
+      = icon('calendar')
+      = issue.due_date.to_s(:medium)
     - if issue.labels.any?
       &nbsp;
       - issue.labels.each do |label|
diff --git a/app/views/shared/_sort_dropdown.html.haml b/app/views/shared/_sort_dropdown.html.haml
index e3a6a5a68b681a84ea62e7113579f72caef58b50..80971309da74fbf41e8843094a88f8acd2da66ae 100644
--- a/app/views/shared/_sort_dropdown.html.haml
+++ b/app/views/shared/_sort_dropdown.html.haml
@@ -20,6 +20,10 @@
         = sort_title_milestone_soon
       = link_to page_filter_path(sort: sort_value_milestone_later) do
         = sort_title_milestone_later
+      = link_to page_filter_path(sort: sort_value_due_date_soon) do
+        = sort_title_due_date_soon if controller_name == "issues"
+      = link_to page_filter_path(sort: sort_value_due_date_later) do
+        = sort_title_due_date_later if controller_name == "issues"
       = link_to page_filter_path(sort: sort_value_upvotes) do
         = sort_title_upvotes
       = link_to page_filter_path(sort: sort_value_downvotes) do
diff --git a/app/views/shared/issuable/_filter.html.haml b/app/views/shared/issuable/_filter.html.haml
index ade0a56b2e7f199a010db125eeee7f1357f9135d..f832f430b2b8a7e2ad806944aba4a28446e89a9c 100644
--- a/app/views/shared/issuable/_filter.html.haml
+++ b/app/views/shared/issuable/_filter.html.haml
@@ -23,6 +23,13 @@
 
         .filter-item.inline.labels-filter
           = render "shared/issuable/label_dropdown"
+
+        - if controller.controller_name == 'issues'
+          .filter-item.inline.due_date-filter
+            = select_tag('due_date', due_date_options,
+              class: 'select2 trigger-submit', include_blank: true,
+              data: {placeholder: 'Due Date'})
+
         .pull-right
           = render 'shared/sort_dropdown'
 
diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml
index 03a615d191c3a94608b436ddf826f088f479ed3a..fb2c727d57a0b9d78195fe1a73711331a64a5b0c 100644
--- a/app/views/shared/issuable/_sidebar.html.haml
+++ b/app/views/shared/issuable/_sidebar.html.haml
@@ -74,6 +74,31 @@
         .selectbox.hide-collapsed
           = f.hidden_field 'milestone_id', value: issuable.milestone_id, id: nil
           = dropdown_tag('Milestone', options: { title: 'Assign milestone', toggle_class: 'js-milestone-select js-extra-options', filter: true, dropdown_class: 'dropdown-menu-selectable', placeholder: 'Search milestones', data: { show_no: true, field_name: "#{issuable.to_ability_name}[milestone_id]", project_id: @project.id, issuable_id: issuable.id, milestones: namespace_project_milestones_path(@project.namespace, @project, :json), ability_name: issuable.to_ability_name, issue_update: issuable_json_path(issuable), use_id: true }})
+      - if issuable.has_attribute? :due_date
+        .block.due_date
+          .sidebar-collapsed-icon
+            = icon('calendar')
+            %span
+              - if issuable.due_date
+                = icon('calendar')
+                = issuable.due_date.to_s(:medium)
+              - else
+                .light None
+          .title.hide-collapsed
+            %label
+              Due Date
+            - if can?(current_user, :"admin_#{issuable.to_ability_name}", @project)
+              .pull-right
+                = link_to 'Edit', '#', class: 'edit-link'
+          .value.hide-collapsed
+            - if issuable.due_date
+              = icon('calendar')
+              = issuable.due_date.to_s(:medium)
+            - else
+              .light None
+          .selectbox.hide-collapsed
+            = f.text_field :due_date
+            = hidden_field_tag :issuable_context
 
       - if issuable.project.labels.any?
         .block.labels
diff --git a/db/migrate/20160310124959_add_due_date_to_issues.rb b/db/migrate/20160310124959_add_due_date_to_issues.rb
new file mode 100644
index 0000000000000000000000000000000000000000..c232387a6f3c35658c6dfcd4ba36b462bd4324ff
--- /dev/null
+++ b/db/migrate/20160310124959_add_due_date_to_issues.rb
@@ -0,0 +1,5 @@
+class AddDueDateToIssues < ActiveRecord::Migration
+  def change
+    add_column :issues, :due_date, :date
+  end
+end
diff --git a/db/schema.rb b/db/schema.rb
index d82c8c1e257baff2da09b3fad108f07b9a44d9f8..699a99c07434d6649d3d30ff3f5b216ec84f36a5 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -366,6 +366,19 @@ ActiveRecord::Schema.define(version: 20160419120017) do
   add_index "emails", ["email"], name: "index_emails_on_email", unique: true, using: :btree
   add_index "emails", ["user_id"], name: "index_emails_on_user_id", using: :btree
 
+  create_table "emoji_awards", force: :cascade do |t|
+    t.string   "name"
+    t.integer  "user_id"
+    t.integer  "awardable_id"
+    t.string   "awardable_type"
+    t.datetime "created_at"
+    t.datetime "updated_at"
+  end
+
+  add_index "emoji_awards", ["awardable_id"], name: "index_emoji_awards_on_awardable_id", using: :btree
+  add_index "emoji_awards", ["awardable_type"], name: "index_emoji_awards_on_awardable_type", using: :btree
+  add_index "emoji_awards", ["user_id"], name: "index_emoji_awards_on_user_id", using: :btree
+
   create_table "events", force: :cascade do |t|
     t.string   "target_type"
     t.integer  "target_id"
@@ -422,6 +435,7 @@ ActiveRecord::Schema.define(version: 20160419120017) do
     t.integer  "moved_to_id"
     t.boolean  "confidential",  default: false
     t.datetime "deleted_at"
+    t.date     "due_date"
   end
 
   add_index "issues", ["assignee_id"], name: "index_issues_on_assignee_id", using: :btree
@@ -431,6 +445,7 @@ ActiveRecord::Schema.define(version: 20160419120017) do
   add_index "issues", ["created_at"], name: "index_issues_on_created_at", using: :btree
   add_index "issues", ["deleted_at"], name: "index_issues_on_deleted_at", using: :btree
   add_index "issues", ["description"], name: "index_issues_on_description_trigram", using: :gin, opclasses: {"description"=>"gin_trgm_ops"}
+  add_index "issues", ["due_date"], name: "index_issues_on_due_date", using: :btree
   add_index "issues", ["milestone_id"], name: "index_issues_on_milestone_id", using: :btree
   add_index "issues", ["project_id", "iid"], name: "index_issues_on_project_id_and_iid", unique: true, using: :btree
   add_index "issues", ["project_id"], name: "index_issues_on_project_id", using: :btree
diff --git a/spec/features/issues_spec.rb b/spec/features/issues_spec.rb
index 35c8f93abc10006c0675d7b5c941fc63d869da1a..ac54a0c2719ee2686a17e66653f71a0e110fbf7b 100644
--- a/spec/features/issues_spec.rb
+++ b/spec/features/issues_spec.rb
@@ -153,6 +153,69 @@ describe 'Issues', feature: true do
       expect(first_issue).to include('baz')
     end
 
+    describe 'sorting by due date' do
+      before :each do
+        foo.due_date = 1.day.from_now
+        foo.save
+        bar.due_date = 6.days.from_now
+        bar.save
+      end
+
+      it 'sorts by recently due date' do
+        visit namespace_project_issues_path(project.namespace, project, sort: sort_value_due_date_soon)
+        expect(first_issue).to include('foo')
+      end
+
+      it 'sorts by least recently due date' do
+        visit namespace_project_issues_path(project.namespace, project, sort: sort_value_due_date_later)
+        expect(first_issue).to include('bar')
+      end
+
+      it 'sorts by least recently due date by excluding nil due dates' do
+        bar.update(due_date: nil)
+        visit namespace_project_issues_path(project.namespace, project, sort: sort_value_due_date_later)
+        expect(first_issue).to include('foo')
+      end
+    end
+
+    describe 'filtering by due date' do
+      before :each do
+        foo.due_date = 1.day.from_now
+        foo.save
+        bar.due_date = 6.days.from_now
+        bar.save
+      end
+
+      it 'filters by none' do
+        visit namespace_project_issues_path(project.namespace, project, due_date: Issue::NO_DUE_DATE[1])
+        expect(page).not_to have_content("foo")
+        expect(page).not_to have_content("bar")
+        expect(page).to have_content("baz")
+      end
+
+      it 'filters by any' do
+        visit namespace_project_issues_path(project.namespace, project, due_date: Issue::ANY_DUE_DATE[1])
+        expect(page).to have_content("foo")
+        expect(page).to have_content("bar")
+        expect(page).to have_content("baz")
+      end
+
+      it 'filters by due to tomorrow' do
+        visit namespace_project_issues_path(project.namespace, project, due_date: Date.tomorrow.to_s)
+        expect(page).to have_content("foo")
+        expect(page).not_to have_content("bar")
+        expect(page).not_to have_content("baz")
+      end
+
+      it 'filters by due in this week' do
+        visit namespace_project_issues_path(project.namespace, project, due_date: 7.days.from_now.to_date.to_s)
+        expect(page).to have_content("foo")
+        expect(page).to have_content("bar")
+        expect(page).not_to have_content("baz")
+      end
+
+    end
+
     describe 'sorting by milestone' do
       before :each do
         foo.milestone = newer_due_milestone