diff --git a/CHANGELOG b/CHANGELOG
index 3af83ddc25664d58fdca2675c08d1788e980cf27..b5bacedc48f2a37b21ac6d996431b48d89a4a8cb 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -20,6 +20,7 @@ v 7.11.0 (unreleased)
   - Don't crash when an MR from a fork has a cross-reference comment from the target project on of its commits.
   - Include commit comments in MR from a forked project.
   - Fix adding new group members from admin area
+  - Query issues, merge requests and milestones with their IID through API (Julien Bianchi)
   - Add default project and snippet visibility settings to the admin web UI.
   -
   - Fix bug where commit data would not appear in some subdirectories (Stan Hu)
diff --git a/doc/api/issues.md b/doc/api/issues.md
index a7dd8b74c35a3f6799c732663d2798ead68db0ba..d407bc35d79dd5009bdd2aa571443fc128a100f8 100644
--- a/doc/api/issues.md
+++ b/doc/api/issues.md
@@ -99,11 +99,13 @@ GET /projects/:id/issues?labels=foo,bar
 GET /projects/:id/issues?labels=foo,bar&state=opened
 GET /projects/:id/issues?milestone=1.0.0
 GET /projects/:id/issues?milestone=1.0.0&state=opened
+GET /projects/:id/issues?iid=42
 ```
 
 Parameters:
 
 - `id` (required) - The ID of a project
+- `iid` (optional) - Return the issue having the given `iid`
 - `state` (optional) - Return `all` issues or just those that are `opened` or `closed`
 - `labels` (optional) - Comma-separated list of label names
 - `milestone` (optional) - Milestone title
diff --git a/doc/api/merge_requests.md b/doc/api/merge_requests.md
index 6a272539e45fb7db43877b74652fe24dbffcb0ed..c1d82ad9576a1043fde82c98d645bb0a5fada8f6 100644
--- a/doc/api/merge_requests.md
+++ b/doc/api/merge_requests.md
@@ -10,11 +10,13 @@ The pagination parameters `page` and `per_page` can be used to restrict the list
 GET /projects/:id/merge_requests
 GET /projects/:id/merge_requests?state=opened
 GET /projects/:id/merge_requests?state=all
+GET /projects/:id/merge_requests?iid=42
 ```
 
 Parameters:
 
 - `id` (required) - The ID of a project
+- `iid` (optional) - Return the request having the given `iid`
 - `state` (optional) - Return `all` requests or just those that are `merged`, `opened` or `closed`
 - `order_by` (optional) - Return requests ordered by `created_at` or `updated_at` fields. Default is `created_at`
 - `sort` (optional) - Return requests sorted in `asc` or `desc` order. Default is `desc`
@@ -388,6 +390,6 @@ Parameters:
 ]
 ```
 
-## Comments on issues
+## Comments on merge requets
 
 Comments are done via the notes resource.
diff --git a/doc/api/milestones.md b/doc/api/milestones.md
index d48b3bcce8aa3fe83ea93db902957e3ac9056d65..a682872826474732966f46908ad7c8fce2518ab5 100644
--- a/doc/api/milestones.md
+++ b/doc/api/milestones.md
@@ -6,6 +6,7 @@ Returns a list of project milestones.
 
 ```
 GET /projects/:id/milestones
+GET /projects/:id/milestones?iid=42
 ```
 
 ```json
@@ -27,6 +28,7 @@ GET /projects/:id/milestones
 Parameters:
 
 - `id` (required) - The ID of a project
+- `iid` (optional) - Return the milestone having the given `iid`
 
 ## Get single milestone
 
diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb
index be133a2920bfaa0105b444b7f1c16391bd530d2f..85e9081680d5554643c2b06df73e2803986c4513 100644
--- a/lib/api/helpers.rb
+++ b/lib/api/helpers.rb
@@ -173,6 +173,10 @@ module API
       end
     end
 
+    def filter_by_iid(items, iid)
+      items.where(iid: iid)
+    end
+
     # error helpers
 
     def forbidden!(reason = nil)
diff --git a/lib/api/issues.rb b/lib/api/issues.rb
index ff062be60404976a99eeeabd2e997e845188e22e..c8db93eb77866730d6fb7c806df2831d66168a12 100644
--- a/lib/api/issues.rb
+++ b/lib/api/issues.rb
@@ -51,6 +51,7 @@ module API
       #
       # Parameters:
       #   id (required) - The ID of a project
+      #   iid (optional) - Return the project issue having the given `iid`
       #   state (optional) - Return "opened" or "closed" issues
       #   labels (optional) - Comma-separated list of label names
       #   milestone (optional) - Milestone title
@@ -66,10 +67,12 @@ module API
       #   GET /projects/:id/issues?labels=foo,bar&state=opened
       #   GET /projects/:id/issues?milestone=1.0.0
       #   GET /projects/:id/issues?milestone=1.0.0&state=closed
+      #   GET /issues?iid=42
       get ":id/issues" do
         issues = user_project.issues
         issues = filter_issues_state(issues, params[:state]) unless params[:state].nil?
         issues = filter_issues_labels(issues, params[:labels]) unless params[:labels].nil?
+        issues = filter_by_iid(issues, params[:iid]) unless params[:iid].nil?
 
         unless params[:milestone].nil?
           issues = filter_issues_milestone(issues, params[:milestone])
diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb
index b252c57faedfb4834276374b646d2723dcc4755a..2216a12a87a5638f59c843736570bb1b211c2011 100644
--- a/lib/api/merge_requests.rb
+++ b/lib/api/merge_requests.rb
@@ -24,6 +24,7 @@ module API
       #
       # Parameters:
       #   id (required) - The ID of a project
+      #   iid (optional) - Return the project MR having the given `iid`
       #   state (optional) - Return requests "merged", "opened" or "closed"
       #   order_by (optional) - Return requests ordered by `created_at` or `updated_at` fields. Default is `created_at`
       #   sort (optional) - Return requests sorted in `asc` or `desc` order. Default is `desc`
@@ -36,11 +37,16 @@ module API
       #   GET /projects/:id/merge_requests?order_by=updated_at
       #   GET /projects/:id/merge_requests?sort=desc
       #   GET /projects/:id/merge_requests?sort=asc
+      #   GET /projects/:id/merge_requests?iid=42
       #
       get ":id/merge_requests" do
         authorize! :read_merge_request, user_project
         merge_requests = user_project.merge_requests
 
+        unless params[:iid].nil?
+          merge_requests = filter_by_iid(merge_requests, params[:iid])
+        end
+
         merge_requests =
           case params["state"]
           when "opened" then merge_requests.opened
@@ -169,8 +175,8 @@ module API
       # Merge MR
       #
       # Parameters:
-      #   id (required)               - The ID of a project
-      #   merge_request_id (required) - ID of MR
+      #   id (required)                   - The ID of a project
+      #   merge_request_id (required)     - ID of MR
       #   merge_commit_message (optional) - Custom merge commit message
       # Example:
       #   PUT /projects/:id/merge_request/:merge_request_id/merge
@@ -209,7 +215,7 @@ module API
       # Get a merge request's comments
       #
       # Parameters:
-      #   id (required) - The ID of a project
+      #   id (required)               - The ID of a project
       #   merge_request_id (required) - ID of MR
       # Examples:
       #   GET /projects/:id/merge_request/:merge_request_id/comments
@@ -225,9 +231,9 @@ module API
       # Post comment to merge request
       #
       # Parameters:
-      #   id (required) - The ID of a project
+      #   id (required)               - The ID of a project
       #   merge_request_id (required) - ID of MR
-      #   note (required) - Text of comment
+      #   note (required)             - Text of comment
       # Examples:
       #   POST /projects/:id/merge_request/:merge_request_id/comments
       #
diff --git a/spec/requests/api/issues_spec.rb b/spec/requests/api/issues_spec.rb
index b6b0427debf93666406cf5180af659bf6af273be..8770786f49a9065e37693662c24a1917b7d1c148 100644
--- a/spec/requests/api/issues_spec.rb
+++ b/spec/requests/api/issues_spec.rb
@@ -194,6 +194,14 @@ describe API::API, api: true  do
       expect(json_response['iid']).to eq(issue.iid)
     end
 
+    it 'should return a project issue by iid' do
+      get api("/projects/#{project.id}/issues?iid=#{issue.iid}", user)
+      response.status.should == 200
+      json_response.first['title'].should == issue.title
+      json_response.first['id'].should == issue.id
+      json_response.first['iid'].should == issue.iid
+    end
+
     it "should return 404 if issue id not found" do
       get api("/projects/#{project.id}/issues/54321", user)
       expect(response.status).to eq(404)
diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb
index 5fca831f9be8d0f611ab4338ac5ff4f1a709fffc..dcd50f73326d21e5331b4c819ba315b041127906 100644
--- a/spec/requests/api/merge_requests_spec.rb
+++ b/spec/requests/api/merge_requests_spec.rb
@@ -115,6 +115,14 @@ describe API::API, api: true  do
       expect(json_response['iid']).to eq(merge_request.iid)
     end
 
+    it 'should return merge_request by iid' do
+      url = "/projects/#{project.id}/merge_requests?iid=#{merge_request.iid}"
+      get api(url, user)
+      response.status.should == 200
+      json_response.first['title'].should == merge_request.title
+      json_response.first['id'].should == merge_request.id
+    end
+
     it "should return a 404 error if merge_request_id not found" do
       get api("/projects/#{project.id}/merge_request/999", user)
       expect(response.status).to eq(404)
diff --git a/spec/requests/api/milestones_spec.rb b/spec/requests/api/milestones_spec.rb
index effb0723476e843bc0e66101baf7e78480bf5b2e..6890dd1f3a7a7cdf9243318b1e4df9abb02c44af 100644
--- a/spec/requests/api/milestones_spec.rb
+++ b/spec/requests/api/milestones_spec.rb
@@ -30,6 +30,13 @@ describe API::API, api: true  do
       expect(json_response['iid']).to eq(milestone.iid)
     end
 
+    it 'should return a project milestone by iid' do
+      get api("/projects/#{project.id}/milestones?iid=#{milestone.iid}", user)
+      response.status.should == 200
+      json_response.first['title'].should == milestone.title
+      json_response.first['id'].should == milestone.id
+    end
+
     it 'should return 401 error if user not authenticated' do
       get api("/projects/#{project.id}/milestones/#{milestone.id}")
       expect(response.status).to eq(401)