diff --git a/math/vecops/inc/ROOT/RVec.hxx b/math/vecops/inc/ROOT/RVec.hxx
index d8b769ca44147aa49f34ec74900615d6231ae896..8742f4658e6ccefb5a81e57e3ac10d41cc7845c4 100644
--- a/math/vecops/inc/ROOT/RVec.hxx
+++ b/math/vecops/inc/ROOT/RVec.hxx
@@ -1447,6 +1447,81 @@ RVec<Common_t> Concatenate(const RVec<T0> &v0, const RVec<T1> &v1)
    return res;
 }
 
+/// Return the angle difference \f$\Delta \phi\f$ of two scalars.
+///
+/// The function computes the closest angle from v1 to v2 with sign and is
+/// therefore in the range \f$[-\pi, \pi]\f$.
+/// The computation is done per default in radians \f$c = \pi\f$ but can be switched
+/// to degrees \f$c = 180\f$.
+template <typename T>
+T DeltaPhi(T v1, T v2, const T c = M_PI)
+{
+   static_assert(std::is_floating_point<T>::value,
+                 "DeltaPhi must be called with floating point values.");
+   auto r = std::fmod(v2 - v1, 2.0 * c);
+   if (r < -c) {
+      r += 2.0 * c;
+   }
+   else if (r > c) {
+      r -= 2.0 * c;
+   }
+   return r;
+}
+
+/// Return the angle difference \f$\Delta \phi\f$ in radians of two vectors.
+///
+/// The function computes the closest angle from v1 to v2 with sign and is
+/// therefore in the range \f$[-\pi, \pi]\f$.
+/// The computation is done per default in radians \f$c = \pi\f$ but can be switched
+/// to degrees \f$c = 180\f$.
+template <typename T>
+RVec<T> DeltaPhi(const RVec<T>& v1, const RVec<T>& v2, const T c = M_PI)
+{
+   using size_type = typename RVec<T>::size_type;
+   const size_type size = v1.size();
+   auto r = RVec<T>(size);
+   for (size_type i = 0; i < size; i++) {
+      r[i] = DeltaPhi(v1[i], v2[i], c);
+   }
+   return r;
+}
+
+/// Return the angle difference \f$\Delta \phi\f$ in radians of a vector and a scalar.
+///
+/// The function computes the closest angle from v1 to v2 with sign and is
+/// therefore in the range \f$[-\pi, \pi]\f$.
+/// The computation is done per default in radians \f$c = \pi\f$ but can be switched
+/// to degrees \f$c = 180\f$.
+template <typename T>
+RVec<T> DeltaPhi(const RVec<T>& v1, T v2, const T c = M_PI)
+{
+   using size_type = typename RVec<T>::size_type;
+   const size_type size = v1.size();
+   auto r = RVec<T>(size);
+   for (size_type i = 0; i < size; i++) {
+      r[i] = DeltaPhi(v1[i], v2, c);
+   }
+   return r;
+}
+
+/// Return the angle difference \f$\Delta \phi\f$ in radians of a scalar and a vector.
+///
+/// The function computes the closest angle from v1 to v2 with sign and is
+/// therefore in the range \f$[-\pi, \pi]\f$.
+/// The computation is done per default in radians \f$c = \pi\f$ but can be switched
+/// to degrees \f$c = 180\f$.
+template <typename T>
+RVec<T> DeltaPhi(T v1, const RVec<T>& v2, const T c = M_PI)
+{
+   using size_type = typename RVec<T>::size_type;
+   const size_type size = v2.size();
+   auto r = RVec<T>(size);
+   for (size_type i = 0; i < size; i++) {
+      r[i] = DeltaPhi(v1, v2[i], c);
+   }
+   return r;
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 /// Print a RVec at the prompt:
 template <class T>
diff --git a/math/vecops/test/CMakeLists.txt b/math/vecops/test/CMakeLists.txt
index 2d3475b204e3620ab21c8f6c5bf0c8255f5265b7..d10053c414a9b6ee7522bc3523416b8ca66e1b98 100644
--- a/math/vecops/test/CMakeLists.txt
+++ b/math/vecops/test/CMakeLists.txt
@@ -1,2 +1,2 @@
-ROOT_ADD_GTEST(vecops_rvec vecops_rvec.cxx LIBRARIES ROOTVecOps RIO Tree)
+ROOT_ADD_GTEST(vecops_rvec vecops_rvec.cxx LIBRARIES Physics ROOTVecOps RIO Tree)
 ROOT_ADD_GTEST(vecops_radoptallocator vecops_radoptallocator.cxx LIBRARIES Core ROOTVecOps)
diff --git a/math/vecops/test/vecops_rvec.cxx b/math/vecops/test/vecops_rvec.cxx
index 1cca9a2d2b85649b0a5b871482475cb7721c2e5c..07b55fc86acc12e11f619fa0cfe75cf9502f03df 100644
--- a/math/vecops/test/vecops_rvec.cxx
+++ b/math/vecops/test/vecops_rvec.cxx
@@ -5,8 +5,10 @@
 #include <TInterpreter.h>
 #include <TTree.h>
 #include <TSystem.h>
+#include <TLorentzVector.h>
 #include <vector>
 #include <sstream>
+#include <cmath>
 
 using namespace ROOT::VecOps;
 
@@ -903,3 +905,59 @@ TEST(VecOps, Concatenate)
    const RVec<float> ref { 0.00000f, 1.00000f, 2.00000f, 7.00000f, 8.00000f, 9.00000f };
    CheckEqual(res, ref);
 }
+
+TEST(VecOps, DeltaPhi)
+{
+   using namespace ROOT::VecOps;
+
+   // Two scalars (radians)
+   // NOTE: These tests include the checks of the poundary effects
+   const float c1 = M_PI;
+   EXPECT_EQ(DeltaPhi(0.f, 2.f), 2.f);
+   EXPECT_EQ(DeltaPhi(1.f, 0.f), -1.f);
+   EXPECT_EQ(DeltaPhi(-0.5f, 0.5f), 1.f);
+   EXPECT_EQ(DeltaPhi(0.f, 2.f * c1 - 1.f), -1.f);
+   EXPECT_EQ(DeltaPhi(0.f, 4.f * c1 - 1.f), -1.f);
+   EXPECT_EQ(DeltaPhi(0.f, -2.f * c1 + 1.f), 1.f);
+   EXPECT_EQ(DeltaPhi(0.f, -4.f * c1 + 1.f), 1.f);
+
+   // Two scalars (degrees)
+   const float c2 = 180.f;
+   EXPECT_EQ(DeltaPhi(0.f, 2.f, c2), 2.f);
+   EXPECT_EQ(DeltaPhi(1.f, 0.f, c2), -1.f);
+   EXPECT_EQ(DeltaPhi(-0.5f, 0.5f, c2), 1.f);
+   EXPECT_EQ(DeltaPhi(0.f, 2.f * c2 - 1.f, c2), -1.f);
+   EXPECT_EQ(DeltaPhi(0.f, 4.f * c2 - 1.f, c2), -1.f);
+   EXPECT_EQ(DeltaPhi(0.f, -2.f * c2 + 1.f, c2), 1.f);
+   EXPECT_EQ(DeltaPhi(0.f, -4.f * c2 + 1.f, c2), 1.f);
+
+   // Two vectors
+   RVec<float> v1 = {0.f, 1.f, -0.5f, 0.f, 0.f, 0.f, 0.f};
+   RVec<float> v2 = {2.f, 0.f, 0.5f, 2.f * c1 - 1.f, 4.f * c1 - 1.f, -2.f * c1 + 1.f, -4.f * c1 + 1.f};
+   auto dphi1 = DeltaPhi(v1, v2);
+   RVec<float> r1 = {2.f, -1.f, 1.f, -1.f, -1.f, 1.f, 1.f};
+   CheckEqual(dphi1, r1);
+
+   auto dphi2 = DeltaPhi(v2, v1);
+   auto r2 = r1 * -1.f;
+   CheckEqual(dphi2, r2);
+
+   // Check against TLorentzVector
+   for (std::size_t i = 0; i < v1.size(); i++) {
+       TLorentzVector p1, p2;
+       p1.SetPtEtaPhiM(1.f, 1.f, v1[i], 1.f);
+       p2.SetPtEtaPhiM(1.f, 1.f, v2[i], 1.f);
+       EXPECT_NEAR(float(p2.DeltaPhi(p1)), dphi1[i], 1e-6);
+   }
+
+   // Vector and scalar
+   RVec<float> v3 = {0.f, 1.f, c1, c1 + 1.f, 2.f * c1, 2.f * c1 + 1.f, -1.f, -c1, -c1 + 1.f, -2.f * c1, -2.f * c1 + 1.f};
+   float v4 = 1.f;
+   auto dphi3 = DeltaPhi(v3, v4);
+   RVec<float> r3 = {1.f, 0.f, 1.f - c1, c1, 1.f, 0.f, 2.f, -c1 + 1.f, c1, 1.f, 0.f};
+   CheckEqual(dphi3, r3);
+
+   auto dphi4 = DeltaPhi(v4, v3);
+   auto r4 = -1.f * r3;
+   CheckEqual(dphi4, r4);
+}
diff --git a/tutorials/vecops/vo007_PhysicsHelpers.C b/tutorials/vecops/vo007_PhysicsHelpers.C
new file mode 100644
index 0000000000000000000000000000000000000000..f6d9a75ab190f1dca3612afe8d7c427f943d29dc
--- /dev/null
+++ b/tutorials/vecops/vo007_PhysicsHelpers.C
@@ -0,0 +1,35 @@
+/// \file
+/// \ingroup tutorial_vecops
+/// \notebook -nodraw
+/// In this tutorial we demonstrate RVec helpers for physics computations such
+/// as angle differences \f$\Delta \phi\f$.
+///
+/// \macro_code
+/// \macro_output
+///
+/// \date March 2019
+/// \author Stefan Wunsch
+
+using namespace ROOT::VecOps;
+
+void vo007_PhysicsHelpers()
+{
+   // The DeltaPhi helper computes the closest angle between angles.
+   // This means that the resulting value is in the range [-pi, pi].
+
+   // Note that the helper also supports to compute the angle difference of an
+   // RVec and a scalar and two scalars. In addition, the computation of the
+   // difference and the behaviour at the boundary can be adjusted to radian and
+   // degrees.
+   RVec<float> phis = {0.0, 1.0, -0.5, M_PI + 1.0};
+   auto idx = Combinations(phis, 2);
+
+   auto phi_1 = Take(phis, idx[0]);
+   auto phi_2 = Take(phis, idx[1]);
+   auto dphi = DeltaPhi(phi_1, phi_2);
+
+   std::cout << "Phi values: " << phis << std::endl;
+   for(std::size_t i = 0; i < idx[0].size(); i++) {
+      std::cout << "DeltaPhi(" << phis[idx[0][i]] << ", " << phis[idx[1][i]] << ") = " << dphi[i] << std::endl;
+   }
+}