diff --git a/source/App/DecoderApp/DecApp.cpp b/source/App/DecoderApp/DecApp.cpp
index 0c029914ab1f569a1f7bb330d057614839943144..3424e6ea64d489006c474c00a36407b85292ba0a 100644
--- a/source/App/DecoderApp/DecApp.cpp
+++ b/source/App/DecoderApp/DecApp.cpp
@@ -122,7 +122,11 @@ uint32_t DecApp::decode()
   }
 
   // main decoder loop
+#if JVET_P0125_EOS_LAYER_SPECIFIC
+  bool loopFiltered[MAX_VPS_LAYERS] = { 0 };
+#else
   bool loopFiltered = false;
+#endif
 
   bool bPicSkipped = false;
 
@@ -207,23 +211,42 @@ uint32_t DecApp::decode()
       }
     }
 
-
+#if JVET_P0125_EOS_LAYER_SPECIFIC
+    if ((bNewPicture || !bitstreamFile || nalu.m_nalUnitType == NAL_UNIT_EOS) && !m_cDecLib.getFirstSliceInSequence(nalu.m_nuhLayerId) && !bPicSkipped)
+#else
     if ((bNewPicture || !bitstreamFile || nalu.m_nalUnitType == NAL_UNIT_EOS) && !m_cDecLib.getFirstSliceInSequence() && !bPicSkipped)
+#endif
     {
+#if JVET_P0125_EOS_LAYER_SPECIFIC
+      if (!loopFiltered[nalu.m_nuhLayerId] || bitstreamFile)
+#else
       if (!loopFiltered || bitstreamFile)
+#endif
       {
         m_cDecLib.executeLoopFilters();
         m_cDecLib.finishPicture( poc, pcListPic );
       }
+#if JVET_P0125_EOS_LAYER_SPECIFIC
+      loopFiltered[nalu.m_nuhLayerId] = (nalu.m_nalUnitType == NAL_UNIT_EOS);
+#else
       loopFiltered = (nalu.m_nalUnitType == NAL_UNIT_EOS);
+#endif
       if (nalu.m_nalUnitType == NAL_UNIT_EOS)
       {
+#if JVET_P0125_EOS_LAYER_SPECIFIC
+        m_cDecLib.setFirstSliceInSequence(true, nalu.m_nuhLayerId);
+#else
         m_cDecLib.setFirstSliceInSequence(true);
+#endif
       }
 
     }
     else if ( (bNewPicture || !bitstreamFile || nalu.m_nalUnitType == NAL_UNIT_EOS ) &&
+#if JVET_P0125_EOS_LAYER_SPECIFIC
+      m_cDecLib.getFirstSliceInSequence(nalu.m_nuhLayerId))
+#else
               m_cDecLib.getFirstSliceInSequence () )
+#endif
     {
       m_cDecLib.setFirstSliceInPicture (true);
     }
diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index 03b4c827d26e0ea0887fa932410760c407bbd80e..ddbbff462bde5acb4ce07de0a4271a584eeb8ba4 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -52,6 +52,8 @@
 
 #define JVET_Q0416_WRAPAROUND_OFFSET                      1  //JVET-Q0416: subtract (CtbSizeY / MinCbSizeY + 2) from wraparound offset before signaling
 
+#define JVET_P0125_EOS_LAYER_SPECIFIC                     1 // JVET-P0125: Specify EOS NAL units to be layer specific
+
 #define JVET_Q0482_REMOVE_CONSTANT_PARAMS                 1 // JVET-Q0482: Remove constant slice header parameter settings in PPS
 
 #define JVET_Q0505_CHROAM_QM_SIGNALING_400                1  //JVET-Q0505: Cleanup of chroma quantization matrix signaling for 400 color format
diff --git a/source/Lib/DecoderLib/DecLib.cpp b/source/Lib/DecoderLib/DecLib.cpp
index 1ab78f0beb0aebc7e078cc48f46acbbdb8d21044..7da085fc3446f050d4f73f460691ce6575451624 100644
--- a/source/Lib/DecoderLib/DecLib.cpp
+++ b/source/Lib/DecoderLib/DecLib.cpp
@@ -62,7 +62,11 @@ bool tryDecodePicture( Picture* pcEncPic, const int expectedPoc, const std::stri
   PicList* pcListPic = NULL;
 
   static bool bFirstCall      = true;             /* TODO: MT */
+#if JVET_P0125_EOS_LAYER_SPECIFIC
+  static bool loopFiltered[MAX_VPS_LAYERS] = { false };            /* TODO: MT */
+#else
   static bool loopFiltered    = false;            /* TODO: MT */
+#endif
   static int  iPOCLastDisplay = -MAX_INT;         /* TODO: MT */
 
   static std::ifstream* bitstreamFile = nullptr;  /* TODO: MT */
@@ -147,9 +151,17 @@ bool tryDecodePicture( Picture* pcEncPic, const int expectedPoc, const std::stri
         }
       }
 
+#if JVET_P0125_EOS_LAYER_SPECIFIC
+      if ((bNewPicture || !*bitstreamFile || nalu.m_nalUnitType == NAL_UNIT_EOS) && !pcDecLib->getFirstSliceInSequence(nalu.m_nuhLayerId))
+#else
       if( ( bNewPicture || !*bitstreamFile || nalu.m_nalUnitType == NAL_UNIT_EOS ) && !pcDecLib->getFirstSliceInSequence() )
+#endif
       {
+#if JVET_P0125_EOS_LAYER_SPECIFIC
+        if (!loopFiltered[nalu.m_nuhLayerId] || *bitstreamFile)
+#else
         if( !loopFiltered || *bitstreamFile )
+#endif
         {
           pcDecLib->finishPictureLight( poc, pcListPic );
 
@@ -344,14 +356,26 @@ bool tryDecodePicture( Picture* pcEncPic, const int expectedPoc, const std::stri
 
 
         }
+#if JVET_P0125_EOS_LAYER_SPECIFIC
+        loopFiltered[nalu.m_nuhLayerId] = (nalu.m_nalUnitType == NAL_UNIT_EOS);
+#else
         loopFiltered = ( nalu.m_nalUnitType == NAL_UNIT_EOS );
+#endif
         if( nalu.m_nalUnitType == NAL_UNIT_EOS )
         {
+#if JVET_P0125_EOS_LAYER_SPECIFIC
+          pcDecLib->setFirstSliceInSequence(true, nalu.m_nuhLayerId);
+#else
           pcDecLib->setFirstSliceInSequence( true );
+#endif
         }
 
       }
+#if JVET_P0125_EOS_LAYER_SPECIFIC
+      else if ((bNewPicture || !*bitstreamFile || nalu.m_nalUnitType == NAL_UNIT_EOS) && pcDecLib->getFirstSliceInSequence(nalu.m_nuhLayerId))
+#else
       else if( ( bNewPicture || !*bitstreamFile || nalu.m_nalUnitType == NAL_UNIT_EOS ) && pcDecLib->getFirstSliceInSequence() )
+#endif
       {
         pcDecLib->setFirstSliceInPicture( true );
       }
@@ -369,7 +393,14 @@ bool tryDecodePicture( Picture* pcEncPic, const int expectedPoc, const std::stri
       pcDecLib = nullptr;
     }
     bFirstCall   = true;
+#if JVET_P0125_EOS_LAYER_SPECIFIC
+    for (int i = 0; i < MAX_VPS_LAYERS; i++)
+    {
+      loopFiltered[i] = false;
+    }
+#else
     loopFiltered = false;
+#endif
     iPOCLastDisplay = -MAX_INT;
 
     if( bytestream )
@@ -421,7 +452,11 @@ DecLib::DecLib()
   , m_prevPOC(MAX_INT)
   , m_prevTid0POC(0)
   , m_bFirstSliceInPicture(true)
+#if JVET_P0125_EOS_LAYER_SPECIFIC
+  , m_bFirstSliceInSequence{ true }
+#else
   , m_bFirstSliceInSequence(true)
+#endif
   , m_prevSliceSkipped(false)
   , m_skippedPOC(0)
   , m_bFirstSliceInBitstream(true)
@@ -1580,9 +1615,15 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl
   //For inference of NoOutputOfPriorPicsFlag
   if (m_apcSlicePilot->getRapPicFlag() || m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR)
   {
+#if JVET_P0125_EOS_LAYER_SPECIFIC
+    if ((m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA && m_bFirstSliceInSequence[nalu.m_nuhLayerId]) ||
+      (m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA && m_apcSlicePilot->getHandleCraAsCvsStartFlag()) ||
+      (m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR && m_bFirstSliceInSequence[nalu.m_nuhLayerId]))
+#else
     if ((m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA && m_bFirstSliceInSequence) ||
         (m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA && m_apcSlicePilot->getHandleCraAsCvsStartFlag()) ||
         (m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR && m_bFirstSliceInSequence))
+#endif
     {
       m_apcSlicePilot->setNoIncorrectPicOutputFlag(true);
     }
@@ -1680,7 +1721,11 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl
   m_prevSliceSkipped = false;
 
   //we should only get a different poc for a new picture (with CTU address==0)
+#if JVET_P0125_EOS_LAYER_SPECIFIC
+  if (m_apcSlicePilot->getPOC() != m_prevPOC && !m_bFirstSliceInSequence[nalu.m_nuhLayerId] && (m_apcSlicePilot->getFirstCtuRsAddrInSlice() != 0))
+#else
   if(m_apcSlicePilot->getPOC() != m_prevPOC && !m_bFirstSliceInSequence && (m_apcSlicePilot->getFirstCtuRsAddrInSlice() != 0))
+#endif
   {
     msg( WARNING, "Warning, the first slice of a picture might have been lost!\n");
   }
@@ -1746,7 +1791,11 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl
   // actual decoding starts here
   xActivateParameterSets( nalu.m_nuhLayerId );
 
+#if JVET_P0125_EOS_LAYER_SPECIFIC
+  m_bFirstSliceInSequence[nalu.m_nuhLayerId] = false;
+#else
   m_bFirstSliceInSequence = false;
+#endif
   m_bFirstSliceInBitstream  = false;
 
 
diff --git a/source/Lib/DecoderLib/DecLib.h b/source/Lib/DecoderLib/DecLib.h
index 4f60dc1840d5828f5040ed0a64d6ecfeb12e1142..a388bd9f9cdb22faff4ed8a081de206fbb42ec3f 100644
--- a/source/Lib/DecoderLib/DecLib.h
+++ b/source/Lib/DecoderLib/DecLib.h
@@ -111,7 +111,11 @@ private:
   int                     m_prevPOC;
   int                     m_prevTid0POC;
   bool                    m_bFirstSliceInPicture;
+#if JVET_P0125_EOS_LAYER_SPECIFIC
+  bool                    m_bFirstSliceInSequence[MAX_VPS_LAYERS];
+#else
   bool                    m_bFirstSliceInSequence;
+#endif
   bool                    m_prevSliceSkipped;
   int                     m_skippedPOC;
   bool                    m_bFirstSliceInBitstream;
@@ -183,8 +187,13 @@ public:
   void  setNoOutputPriorPicsFlag (bool val) { m_isNoOutputPriorPics = val; }
   void  setFirstSliceInPicture (bool val)  { m_bFirstSliceInPicture = val; }
   bool  getFirstSliceInPicture () const  { return m_bFirstSliceInPicture; }
+#if JVET_P0125_EOS_LAYER_SPECIFIC
+  bool  getFirstSliceInSequence(int layer) const { return m_bFirstSliceInSequence[layer]; }
+  void  setFirstSliceInSequence(bool val, int layer) { m_bFirstSliceInSequence[layer] = val; }
+#else
   bool  getFirstSliceInSequence () const   { return m_bFirstSliceInSequence; }
   void  setFirstSliceInSequence (bool val) { m_bFirstSliceInSequence = val; }
+#endif
   void  setDecodedSEIMessageOutputStream(std::ostream *pOpStream) { m_pDecodedSEIOutputStream = pOpStream; }
   uint32_t  getNumberOfChecksumErrorsDetected() const { return m_numberOfChecksumErrorsDetected; }