diff --git a/config/vufind/VoyagerRestful.ini b/config/vufind/VoyagerRestful.ini
index d1e6f322f2e956da4a24b1671d6d32203cf9a25e..261246515ee22043d9aa873880dddef1c24cef97 100644
--- a/config/vufind/VoyagerRestful.ini
+++ b/config/vufind/VoyagerRestful.ini
@@ -107,6 +107,11 @@ extraHoldFields = comments:requiredByDate:pickUpLocation
 ; 3) a value within the Location IDs returned by getPickUpLocations()
 defaultPickUpLocation = ""
 
+; By default the pick up location list is sorted alphabetically. This setting can be
+; used to manually set the order by entering location IDs as a colon-separated list.
+; You can also disable sorting by setting this to false.
+;pickUpLocationOrder = 158:155
+
 ; The maximum number of holding items to generate request links for. The process of
 ; checking the API for a valid hold is intensive. Any hold items above this this
 ; limit will have their hold status checked via ajax or when a user clicks on the
diff --git a/module/VuFind/src/VuFind/ILS/Driver/VoyagerRestful.php b/module/VuFind/src/VuFind/ILS/Driver/VoyagerRestful.php
index 9c2f0a1750089070e6ffe4d229cca0f2df7319be..8aa285220bf0b84659df416782011a327f8e7cbe 100644
--- a/module/VuFind/src/VuFind/ILS/Driver/VoyagerRestful.php
+++ b/module/VuFind/src/VuFind/ILS/Driver/VoyagerRestful.php
@@ -770,6 +770,32 @@ class VoyagerRestful extends Voyager implements \VuFindHttp\HttpServiceAwareInte
                 ];
             }
         }
+
+        // Do we need to sort pickup locations? If the setting is false, don't
+        // bother doing any more work. If it's not set at all, default to
+        // alphabetical order.
+        $orderSetting = isset($this->config['Holds']['pickUpLocationOrder'])
+            ? $this->config['Holds']['pickUpLocationOrder'] : 'default';
+        if (count($pickResponse) > 1 && !empty($orderSetting)) {
+            $locationOrder = $orderSetting === 'default'
+                ? [] : array_flip(explode(':', $orderSetting));
+            $sortFunction = function ($a, $b) use ($locationOrder) {
+                $aLoc = $a['locationID'];
+                $bLoc = $b['locationID'];
+                if (isset($locationOrder[$aLoc])) {
+                    if (isset($locationOrder[$bLoc])) {
+                        return $locationOrder[$aLoc] - $locationOrder[$bLoc];
+                    }
+                    return -1;
+                }
+                if (isset($locationOrder[$bLoc])) {
+                    return 1;
+                }
+                return strcasecmp($a['locationDisplay'], $b['locationDisplay']);
+            };
+            usort($pickResponse, $sortFunction);
+        }
+
         return $pickResponse;
     }