diff --git a/blocks/globalsearch/block_globalsearch.php b/blocks/globalsearch/block_globalsearch.php
index 7dd3057b63c..d3d96b20662 100644
--- a/blocks/globalsearch/block_globalsearch.php
+++ b/blocks/globalsearch/block_globalsearch.php
@@ -78,6 +78,12 @@ class block_globalsearch extends block_base {
             'type' => 'text', 'size' => '15');
         $this->content->text .= html_writer::empty_tag('input', $inputoptions);
 
+        // Context id.
+        if ($this->page->context && $this->page->context->contextlevel !== CONTEXT_SYSTEM) {
+            $this->content->text .= html_writer::empty_tag('input', ['type' => 'hidden',
+                    'name' => 'context', 'value' => $this->page->context->id]);
+        }
+
         // Search button.
         $this->content->text .= html_writer::tag('button', get_string('search', 'search'),
             array('id' => 'searchform_button', 'type' => 'submit', 'title' => 'globalsearch', 'class' => 'btn btn-secondary'));
diff --git a/lang/en/search.php b/lang/en/search.php
index 096722d5a91..552d9b6064f 100644
--- a/lang/en/search.php
+++ b/lang/en/search.php
@@ -53,6 +53,7 @@ $string['engineserverstatus'] = 'The search engine is not available. Please cont
 $string['enteryoursearchquery'] = 'Enter your search query';
 $string['errors'] = 'Errors';
 $string['errorareanotavailable'] = '{$a} search area is not available.';
+$string['everywhere'] = 'Everywhere you can access';
 $string['filesinindexdirectory'] = 'Files in index directory';
 $string['filterheader'] = 'Filter';
 $string['fromtime'] = 'Modified after';
@@ -89,6 +90,7 @@ $string['searcharea'] = 'Search area';
 $string['searching'] = 'Searching in ...';
 $string['searchnotpermitted'] = 'You are not allowed to do a search';
 $string['searchsetupdescription'] = 'The following steps help you to set up Moodle global search.';
+$string['searchwithin'] = 'Search within';
 $string['seconds'] = 'seconds';
 $string['solutions'] = 'Solutions';
 $string['statistics'] = 'Statistics';
diff --git a/lib/outputrenderers.php b/lib/outputrenderers.php
index 83c74a3d749..4fbdedce39f 100644
--- a/lib/outputrenderers.php
+++ b/lib/outputrenderers.php
@@ -3259,6 +3259,10 @@ EOD;
 
         $contents = html_writer::tag('label', get_string('enteryoursearchquery', 'search'),
             array('for' => 'id_q_' . $id, 'class' => 'accesshide')) . html_writer::tag('input', '', $inputattrs);
+        if ($this->page->context && $this->page->context->contextlevel !== CONTEXT_SYSTEM) {
+            $contents .= html_writer::empty_tag('input', ['type' => 'hidden',
+                    'name' => 'context', 'value' => $this->page->context->id]);
+        }
         $searchinput = html_writer::tag('form', $contents, $formattrs);
 
         return html_writer::tag('div', $searchicon . $searchinput, array('class' => 'search-input-wrapper nav-link', 'id' => $id));
diff --git a/search/classes/output/form/search.php b/search/classes/output/form/search.php
index 8364e98eaba..3652de78bef 100644
--- a/search/classes/output/form/search.php
+++ b/search/classes/output/form/search.php
@@ -48,6 +48,13 @@ class search extends \moodleform {
         $mform->setType('q', PARAM_TEXT);
         $mform->addRule('q', get_string('required'), 'required', null, 'client');
 
+        // Show the 'search within' option if the user came from a particular context.
+        if (!empty($this->_customdata['searchwithin'])) {
+            $mform->addElement('select', 'searchwithin', get_string('searchwithin', 'search'),
+                    $this->_customdata['searchwithin']);
+            $mform->setDefault('searchwithin', '');
+        }
+
         $mform->addElement('header', 'filtersection', get_string('filterheader', 'search'));
         $mform->setExpanded('filtersection', false);
 
@@ -79,12 +86,21 @@ class search extends \moodleform {
         $mform->addElement('course', 'courseids', get_string('courses', 'core'), $options);
         $mform->setType('courseids', PARAM_INT);
 
+        // Course options should be hidden if we choose to search within a specific location.
+        if (!empty($this->_customdata['searchwithin'])) {
+            $mform->hideIf('courseids', 'searchwithin', 'ne', '');
+        }
+
         $mform->addElement('date_time_selector', 'timestart', get_string('fromtime', 'search'), array('optional' => true));
         $mform->setDefault('timestart', 0);
 
         $mform->addElement('date_time_selector', 'timeend', get_string('totime', 'search'), array('optional' => true));
         $mform->setDefault('timeend', 0);
 
+        // Source context i.e. the page they came from when they clicked search.
+        $mform->addElement('hidden', 'context');
+        $mform->setType('context', PARAM_INT);
+
         $this->add_action_buttons(false, get_string('search', 'search'));
     }
 }
diff --git a/search/index.php b/search/index.php
index 9c67e3dfde4..ece070ca488 100644
--- a/search/index.php
+++ b/search/index.php
@@ -27,6 +27,7 @@ require_once(__DIR__ . '/../config.php');
 $page = optional_param('page', 0, PARAM_INT);
 $q = optional_param('q', '', PARAM_NOTAGS);
 $title = optional_param('title', '', PARAM_NOTAGS);
+$contextid = optional_param('context', 0, PARAM_INT);
 // Moving areaids, courseids, timestart, and timeend further down as they might come as an array if they come from the form.
 
 $context = context_system::instance();
@@ -55,8 +56,23 @@ if (\core_search\manager::is_global_search_enabled() === false) {
 
 $search = \core_search\manager::instance();
 
-// We first get the submitted data as we want to set it all in the page URL.
-$mform = new \core_search\output\form\search(null, array('searchengine' => $search->get_engine()->get_plugin_name()));
+// Set up custom data for form.
+$customdata = ['searchengine' => $search->get_engine()->get_plugin_name()];
+if ($contextid) {
+    // When a context is supplied, check if it's within course level. If so, show dropdown.
+    $context = context::instance_by_id($contextid);
+    $coursecontext = $context->get_course_context(false);
+    if ($coursecontext) {
+        $searchwithin = [];
+        $searchwithin[''] = get_string('everywhere', 'search');
+        $searchwithin['course'] = $coursecontext->get_context_name();
+        if ($context->contextlevel !== CONTEXT_COURSE) {
+            $searchwithin['context'] = $context->get_context_name();
+        }
+        $customdata['searchwithin'] = $searchwithin;
+    }
+}
+$mform = new \core_search\output\form\search(null, $customdata);
 
 $data = $mform->get_data();
 if (!$data && $q) {
@@ -77,9 +93,25 @@ if (!$data && $q) {
     }
     $data->timestart = optional_param('timestart', 0, PARAM_INT);
     $data->timeend = optional_param('timeend', 0, PARAM_INT);
+
+    $data->context = $contextid;
+
     $mform->set_data($data);
 }
 
+// Convert the 'search within' option, if used, to course or context restrictions.
+if ($data && !empty($data->searchwithin)) {
+    switch ($data->searchwithin) {
+        case 'course':
+            $data->courseids = [$coursecontext->instanceid];
+            break;
+        case 'context':
+            $data->courseids = [$coursecontext->instanceid];
+            $data->contextids = [$context->id];
+            break;
+    }
+}
+
 // Set the page URL.
 $urlparams = array('page' => $page);
 if ($data) {
diff --git a/search/tests/behat/search_query.feature b/search/tests/behat/search_query.feature
index 129bbb7204b..e3d9b3502d3 100644
--- a/search/tests/behat/search_query.feature
+++ b/search/tests/behat/search_query.feature
@@ -7,10 +7,13 @@ Feature: Use global search interface
   Background:
     Given the following config values are set as admin:
       | enableglobalsearch | 1 |
+    And the following "courses" exist:
+      | shortname | fullname   |
+      | F1        | Amphibians |
     And the following "activities" exist:
-      | activity | name       | intro      | course               | idnumber |
-      | page     | PageName1  | PageDesc1  | Acceptance test site | PAGE1    |
-      | forum    | ForumName1 | ForumDesc1 | Acceptance test site | FORUM1   |
+      | activity | name       | intro      | course | idnumber |
+      | page     | PageName1  | PageDesc1  | F1     | PAGE1    |
+      | forum    | ForumName1 | ForumDesc1 | F1     | FORUM1   |
     And I log in as "admin"
 
   @javascript
@@ -47,3 +50,44 @@ Feature: Use global search interface
     # Check the link works.
     And I follow "ForumName1"
     And I should see "ForumName1" in the ".breadcrumb" "css_element"
+
+  @javascript
+  Scenario: Search starting from site context (no within option)
+    Given global search expects the query "frogs" and will return:
+      | type     | idnumber |
+      | activity | PAGE1    |
+    When I search for "frogs" using the header global search box
+    And I expand all fieldsets
+    Then I should not see "Search within"
+    And I should see "Courses"
+
+  @javascript
+  Scenario: Search starting from course context (within option lists course)
+    Given global search expects the query "frogs" and will return:
+      | type     | idnumber |
+      | activity | PAGE1    |
+    When I am on "Amphibians" course homepage
+    And I search for "frogs" using the header global search box
+    And I expand all fieldsets
+    Then I should see "Search within"
+    And I select "Everywhere you can access" from the "Search within" singleselect
+    And I should see "Courses"
+    And I select "Course: Amphibians" from the "Search within" singleselect
+    And I should not see "Courses"
+
+  @javascript
+  Scenario: Search starting from forum context (within option lists course and forum)
+    Given global search expects the query "frogs" and will return:
+      | type     | idnumber |
+      | activity | PAGE1    |
+    When I am on "Amphibians" course homepage
+    And I follow "ForumName1"
+    And I search for "frogs" using the header global search box
+    And I expand all fieldsets
+    And I should see "Search within"
+    And I select "Everywhere you can access" from the "Search within" singleselect
+    And I should see "Courses"
+    And I select "Course: Amphibians" from the "Search within" singleselect
+    And I should not see "Courses"
+    And I select "Forum: ForumName1" from the "Search within" singleselect
+    And I should not see "Courses"