diff --git a/Framework/Crystal/src/OptimizeCrystalPlacement.cpp b/Framework/Crystal/src/OptimizeCrystalPlacement.cpp
index b5f8e8e5c3f3ad2d14c54e26370d8db146d718c4..2b02a4e69a1f9a34c43e7162ecb077950fce8b77 100644
--- a/Framework/Crystal/src/OptimizeCrystalPlacement.cpp
+++ b/Framework/Crystal/src/OptimizeCrystalPlacement.cpp
@@ -449,7 +449,7 @@ void OptimizeCrystalPlacement::exec() {
   UBinv.Invert();
   UBinv /= (2 * M_PI);
   for (int i = 0; i < outPeaks->getNumberPeaks(); ++i) {
-
+    outPeaks->getPeak(i).setSamplePos(newSampPos);
     int RunNum = outPeaks->getPeak(i).getRunNumber();
     std::string RunNumStr = std::to_string(RunNum);
     Matrix<double> GonMatrix;
diff --git a/Framework/DataObjects/inc/MantidDataObjects/Peak.h b/Framework/DataObjects/inc/MantidDataObjects/Peak.h
index 39d9aec99c26b65409f77754d669928edd6a39ca..30a0ef9c4b6118c39ea949fc2b4a6ae28339fc67 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/Peak.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/Peak.h
@@ -110,6 +110,8 @@ public:
   void setBankName(std::string m_bankName);
   void setHKL(double H, double K, double L) override;
   void setHKL(const Mantid::Kernel::V3D &HKL) override;
+  void setSamplePos(double samX, double samY, double samZ) override;
+  void setSamplePos(const Mantid::Kernel::V3D &XYZ) override;
   void resetHKL();
 
   Mantid::Kernel::V3D getQLabFrame() const override;
@@ -160,6 +162,7 @@ public:
   int getPeakNumber() const override;
 
   virtual Mantid::Kernel::V3D getDetPos() const override;
+  virtual Mantid::Kernel::V3D getSamplePos() const override;
   double getL1() const override;
   double getL2() const override;
 
diff --git a/Framework/DataObjects/src/Peak.cpp b/Framework/DataObjects/src/Peak.cpp
index d498a4142936962325d4672c7b4587ba10b28299..8dc87b49aadf191b43ba3561a19550cc2d23fd42 100644
--- a/Framework/DataObjects/src/Peak.cpp
+++ b/Framework/DataObjects/src/Peak.cpp
@@ -811,6 +811,27 @@ void Peak::setHKL(const Mantid::Kernel::V3D &HKL) {
   m_L = HKL.Z();
 }
 
+/** Set sample position
+ *
+ * @ doubles x,y,z-> samplePos(x), samplePos(y), samplePos(z)
+ */
+void Peak::setSamplePos(double samX, double samY, double samZ) {
+
+  this->samplePos[0] = samX;
+  this->samplePos[1] = samY;
+  this->samplePos[2] = samZ;
+}
+
+/** Set sample position
+ *
+ * @param XYZ :: vector x,y,z-> samplePos(x), samplePos(y), samplePos(z)
+ */
+void Peak::setSamplePos(const Mantid::Kernel::V3D &XYZ) {
+
+  this->samplePos[0] = XYZ[0];
+  this->samplePos[1] = XYZ[1];
+  this->samplePos[2] = XYZ[2];
+}
 //----------------------------------------------------------------------------------------------
 /** Return the # of counts in the bin at its peak*/
 double Peak::getBinCount() const { return m_binCount; }
@@ -923,6 +944,10 @@ void Peak::setPeakNumber(int m_peakNumber) {
 /** Return the detector position vector */
 Mantid::Kernel::V3D Peak::getDetPos() const { return detPos; }
 
+// -------------------------------------------------------------------------------------
+/** Return the sample position vector */
+Mantid::Kernel::V3D Peak::getSamplePos() const { return samplePos; }
+
 // -------------------------------------------------------------------------------------
 /** Return the L1 flight path length (source to sample), in meters. */
 double Peak::getL1() const { return (samplePos - sourcePos).norm(); }
diff --git a/Framework/DataObjects/test/PeakTest.h b/Framework/DataObjects/test/PeakTest.h
index ff5211b6efc3f8412a5341aa23295c51d9574907..8dc69662462f5fae0aa29db5403251d716860e7e 100644
--- a/Framework/DataObjects/test/PeakTest.h
+++ b/Framework/DataObjects/test/PeakTest.h
@@ -236,6 +236,14 @@ public:
     TS_ASSERT_EQUALS(p.getHKL(), V3D(1.0, 2.0, 3.0));
   }
 
+  void test_samplePos() {
+    Peak p(inst, 10000, 2.0);
+    p.setSamplePos(1.0, 1.0, 1.0);
+    TS_ASSERT_EQUALS(p.getSamplePos(), V3D(1.0, 1.0, 1.0));
+    p.setSamplePos(V3D(2.0, 2.0, 2.0));
+    TS_ASSERT_EQUALS(p.getSamplePos(), V3D(2.0, 2.0, 2.0));
+  }
+
   void test_getBank_and_row() {
     Peak p(inst, 10000, 2.0);
     TS_ASSERT_EQUALS(p.getBankName(), "bank1")
diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/IPeak.h b/Framework/Geometry/inc/MantidGeometry/Crystal/IPeak.h
index 1d15fe3bbf791d2c2fa279f1fb09533e4a4e0997..6a50101841cbc07f241a0ff7e5ec394cf8dae3a4 100644
--- a/Framework/Geometry/inc/MantidGeometry/Crystal/IPeak.h
+++ b/Framework/Geometry/inc/MantidGeometry/Crystal/IPeak.h
@@ -50,6 +50,9 @@ public:
   virtual void setL(double m_L) = 0;
   virtual void setHKL(double H, double K, double L) = 0;
   virtual void setHKL(const Mantid::Kernel::V3D &HKL) = 0;
+  virtual void setSamplePos(double samX, double samY, double samZ) = 0;
+  virtual void setSamplePos(const Mantid::Kernel::V3D &XYZ) = 0;
+  virtual Mantid::Kernel::V3D getSamplePos() const = 0;
   virtual Mantid::Kernel::V3D getDetectorPosition() const = 0;
   virtual Mantid::Kernel::V3D getDetectorPositionNoCheck() const = 0;
 
diff --git a/Framework/Geometry/test/MockObjects.h b/Framework/Geometry/test/MockObjects.h
index 2d489ef0c9112c499ada8bab332227e43f080f64..cc3728edbbf44ff265ff7c1257a8e84306e28e68 100644
--- a/Framework/Geometry/test/MockObjects.h
+++ b/Framework/Geometry/test/MockObjects.h
@@ -81,11 +81,14 @@ public:
   MOCK_CONST_METHOD0(getK, double());
   MOCK_CONST_METHOD0(getL, double());
   MOCK_CONST_METHOD0(getHKL, Mantid::Kernel::V3D());
+  MOCK_CONST_METHOD0(getSamplePos, Mantid::Kernel::V3D());
   MOCK_METHOD1(setH, void(double m_H));
   MOCK_METHOD1(setK, void(double m_K));
   MOCK_METHOD1(setL, void(double m_L));
   MOCK_METHOD3(setHKL, void(double H, double K, double L));
   MOCK_METHOD1(setHKL, void(const Mantid::Kernel::V3D &HKL));
+  MOCK_METHOD3(setSamplePos, void(double samX, double samY, double samZ));
+  MOCK_METHOD1(setSamplePos, void(const Mantid::Kernel::V3D &XYZ));
   MOCK_CONST_METHOD0(getQLabFrame, Mantid::Kernel::V3D());
   MOCK_CONST_METHOD0(getQSampleFrame, Mantid::Kernel::V3D());
   MOCK_METHOD0(findDetector, bool());
diff --git a/Framework/PythonInterface/mantid/api/src/Exports/IPeak.cpp b/Framework/PythonInterface/mantid/api/src/Exports/IPeak.cpp
index a159b756332a3034e33af9c448993a0526673a5e..a68b1f2ac0f0d12848fca94b5c5c756619ce0c57 100644
--- a/Framework/PythonInterface/mantid/api/src/Exports/IPeak.cpp
+++ b/Framework/PythonInterface/mantid/api/src/Exports/IPeak.cpp
@@ -87,9 +87,21 @@ void export_IPeak() {
       .def("getL", &IPeak::getL, arg("self"), "Get the L index of the peak")
       .def("getHKL", &IPeak::getHKL, arg("self"),
            "Get HKL as a :class:`~mantid.kernel.V3D` object")
+      .def("getSamplePos", &IPeak::getSamplePos, arg("self"),
+           "Get the cached samplePos as a :class:`~mantid.kernel.V3D` object")
       .def("setHKL", (void (IPeak::*)(double, double, double)) & IPeak::setHKL,
            (arg("self"), arg("h"), arg("k"), arg("l")),
            "Set the HKL values of this peak")
+      .def("setSamplePos",
+           (void (IPeak::*)(double, double, double)) & IPeak::setSamplePos,
+           (arg("self"), arg("samX"), arg("samY"), arg("samZ")),
+           "Set the samplePos value of this peak.  It does not set the "
+           "instrument sample position.")
+      .def("setSamplePos",
+           (void (IPeak::*)(const Mantid::Kernel::V3D &)) & IPeak::setSamplePos,
+           (arg("self"), arg("newPos")),
+           "Set the samplePos value of this peak.  It does not set the "
+           "instrument sample position.")
       .def("setH", &IPeak::setH, (arg("self"), arg("h")),
            "Get the H index of the peak")
       .def("setK", &IPeak::setK, (arg("self"), arg("k")),
diff --git a/docs/source/release/v3.14.0/diffraction.rst b/docs/source/release/v3.14.0/diffraction.rst
index b26d90a4528cc052d4ea2e2e62b4b8773fbe8897..1554376ec0872acafbdaa51876f30bcf247c58f5 100644
--- a/docs/source/release/v3.14.0/diffraction.rst
+++ b/docs/source/release/v3.14.0/diffraction.rst
@@ -49,6 +49,8 @@ Bugfixes
 - :ref:`FindPeaksMD <algm-FindPeaksMD>` now finds peaks correctly with the crystallography convention setting and reduction with crystallography convention is tested with a system test.
 - :ref:`SaveIsawPeaks <algm-SaveIsawPeaks>` does not have duplicate peak numbers when saving PeaksWorkspaces with more than one RunNumber.
 
+- :ref:`OptimizeCrystalPlacement <algm-OptimizeCrystalPlacement>` now updates the sample location used by peaks.  Previously, the sample was effectively left unmoved.
+
 Powder Diffraction
 ------------------