diff --git a/TileCalorimeter/TileMonitoring/CMakeLists.txt b/TileCalorimeter/TileMonitoring/CMakeLists.txt
index c72c669f6dcc65cdf587933f8957695d38a9277a..15ba99f5ce25e930d223135a8fafede6479b41f6 100644
--- a/TileCalorimeter/TileMonitoring/CMakeLists.txt
+++ b/TileCalorimeter/TileMonitoring/CMakeLists.txt
@@ -74,3 +74,8 @@ atlas_add_test( TileDQFragMonitorAlgorithm_test
                 SCRIPT python -m TileMonitoring.TileDQFragMonitorAlgorithm
                 PROPERTIES TIMEOUT 300
                 POST_EXEC_SCRIPT nopost.sh)
+
+atlas_add_test( TileMBTSMonitorAlgorithm_test
+                SCRIPT python -m TileMonitoring.TileMBTSMonitorAlgorithm
+                PROPERTIES TIMEOUT 300
+                POST_EXEC_SCRIPT nopost.sh)
diff --git a/TileCalorimeter/TileMonitoring/python/TileMBTSMonitorAlgorithm.py b/TileCalorimeter/TileMonitoring/python/TileMBTSMonitorAlgorithm.py
new file mode 100644
index 0000000000000000000000000000000000000000..8d1ae560a0ec6a4206824404c664e8edfc1027fb
--- /dev/null
+++ b/TileCalorimeter/TileMonitoring/python/TileMBTSMonitorAlgorithm.py
@@ -0,0 +1,238 @@
+#
+#  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+#
+
+'''
+@file TileMBTSMonitorAlgorithm.py
+@brief Python configuration of TileMBTSMonitorAlgorithm algorithm for the Run III
+'''
+
+
+def TileMBTSMonitoringConfig(flags, **kwargs):
+
+    ''' Function to configure TileMBTSMonitorAlgorithm algorithm in the monitoring system.'''
+
+    # Define one top-level monitoring algorithm. The new configuration
+    # framework uses a component accumulator.
+    from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
+    result = ComponentAccumulator()
+
+    from TileRecUtils.TileDQstatusConfig import TileDQstatusAlgCfg
+    result.merge( TileDQstatusAlgCfg(flags) )
+
+    from TileGeoModel.TileGMConfig import TileGMCfg
+    result.merge(TileGMCfg(flags))
+
+    from LArGeoAlgsNV.LArGMConfig import LArGMCfg
+    result.merge(LArGMCfg(flags))
+
+    from TileConditions.TileCablingSvcConfig import TileCablingSvcCfg
+    result.merge( TileCablingSvcCfg(flags) )
+
+    # The following class will make a sequence, configure algorithms, and link
+    # them to GenericMonitoringTools
+    from AthenaMonitoring import AthMonitorCfgHelper
+    helper = AthMonitorCfgHelper(flags,'TileMonitoring')
+
+    # Adding an TileMBTSMonitorAlgorithm algorithm to the helper
+    from TileMonitoring.TileMonitoringConf import TileMBTSMonitorAlgorithm
+    tileMBTSMonAlg = helper.addAlgorithm(TileMBTSMonitorAlgorithm, 'TileMBTSMonAlg')
+
+    tileMBTSMonAlg.TriggerChain = ''
+
+    for k, v in kwargs.items():
+        setattr(tileMBTSMonAlg, k, v)
+
+    if 'FillHistogramsPerMBTS' in kwargs:
+        fillHistogramPerMBTS = kwargs['FillHistogramsPerMBTS']
+    else:
+        fillHistogramPerMBTS = tileMBTSMonAlg.getDefaultProperty('FillHistogramsPerMBTS')
+
+    # 1) Configure histogram with TileMBTSMonAlg algorithm execution time
+    executeTimeGroup = helper.addGroup(tileMBTSMonAlg, 'TileMBTSMonExecuteTime', 'Tile/')
+    executeTimeGroup.defineHistogram('TIME_execute', path = 'MBTS', type='TH1F',
+                                     title = 'Time for execute TileMBTSMonAlg algorithm;time [#mus]',
+                                     xbins = 100, xmin = 0, xmax = 100000)
+
+
+    run = str(flags.Input.RunNumber[0])
+    numberOfMBTS = 32
+
+    labelsMBTS  =  ['MBTSA' + ('0' if x < 10 else '') + str(x) for x in range(0, numberOfMBTS / 2)]
+    labelsMBTS +=  ['MBTSC' + ('0' if x < 10 else '') + str(x) for x in range(0, numberOfMBTS / 2)]
+
+
+    # 2) Configure MBTS occupancy histogram
+    occupancyGroup = helper.addGroup(tileMBTSMonAlg, 'TileOccupancyMBTS', 'Tile')
+    occupancyGroup.defineHistogram('EnergyCounter;Occupancy', path = 'MBTS/Cell', type='TH1F', weight = 'SummaryEnergy',
+                                   labels = labelsMBTS, title = 'Run ' + run + ': MBTS Occupancy',
+                                   xbins = numberOfMBTS, xmin = 0, xmax = numberOfMBTS)
+
+    # 3) Configure summary energy histogram
+    energySummaryGroup = helper.addGroup(tileMBTSMonAlg, 'TileEnergySummaryMBTS', 'Tile')
+    energySummaryGroup.defineHistogram('EnergyCounter,SummaryEnergy;SummaryEnergy', path = 'MBTS/Cell', type='TProfile',
+                                       title = 'Run ' + run + ': Average MBTS Energy;;Average Energy [pC]',
+                                       labels = labelsMBTS, xbins = numberOfMBTS, xmin = 0, xmax = numberOfMBTS)
+
+    # 4) Configure histogram with average MBTS time (energy above threshold)
+    timeSummaryGroup = helper.addGroup(tileMBTSMonAlg, 'TileTimeSummaryMBTS', 'Tile')
+    timeSummaryGroup.defineHistogram('TimeCounter,SummaryTime;SummaryTime', path = 'MBTS/Cell', type='TProfile',
+                                     title = 'Run ' + run + ': Average MBTS Time (Energy above threshold);;Average Time [ns]',
+                                     labels = labelsMBTS, xbins = numberOfMBTS, xmin = 0, xmax = numberOfMBTS)
+
+    # 5) Configure histogram with time of MBTS on A side
+    timeAGroup = helper.addGroup(tileMBTSMonAlg, 'TileTimeMBTSA', 'Tile')
+    timeAGroup.defineHistogram('TimeA;Time_A', path = 'MBTS/Cell', type='TH1F',
+                               title = 'Run ' + run + ': Time of MBTS on A side;Time [ns]',
+                               xbins = 151, xmin = -75.5, xmax = 75.5)
+
+    # 6) Configure histogram time of MBTS on C side
+    timeCGroup = helper.addGroup(tileMBTSMonAlg, 'TileTimeMBTSC', 'Tile')
+    timeCGroup.defineHistogram('TimeC;Time_C', path = 'MBTS/Cell', type='TH1F',
+                               title = 'Run ' + run + ': Time of MBTS on C side;Time [ns]',
+                               xbins = 151, xmin = -75.5, xmax = 75.5)
+
+    # 7) Configure histogram with time difference between MBTS on A and C sides
+    timeDifferenceGroup = helper.addGroup(tileMBTSMonAlg, 'TileTimeDifferenceMBTS', 'Tile')
+    timeDifferenceGroup.defineHistogram('TimeDifference;TimeDiff_A-C', path = 'MBTS/Cell', type='TH1F',
+                                        title = 'Run ' + run + ': Time difference between MBTS on A and C sides;Time [ns]',
+                                        xbins = 151, xmin = -75.5, xmax = 75.5)
+
+    # 8) Configure histogram with time difference between MBTS on A and C sides vs luminosity block
+    timeDifferenceLBGroup = helper.addGroup(tileMBTSMonAlg, 'TileTimeDifferenceMBTSLB', 'Tile')
+    timeDifferenceLBGroup.defineHistogram('lumiBlock,TimeDifference;TimeDiff_A-C_LB', path = 'MBTS/Cell', type='TH2F',
+                                          title = ('Run ' + run + ': Time difference between MBTS on A and C sides vs LumiBlock'
+                                                   + ';Luminosity Block;Time difference A-side - C-side [ns]'),
+                                          xbins = 1000, xmin = -0.5, xmax = 999.5, ybins = 151, ymin = -75.5, ymax = 75.5)
+
+    # 9) Configure histogram with coincident Hits (energy) between two MBTS counters
+    labelsCoincidentMBTS = labelsMBTS + labelsMBTS
+    coincidentHitsGroup = helper.addGroup(tileMBTSMonAlg, 'TileCoincidentHitsMBTS', 'Tile')
+    coincidentHitsGroup.defineHistogram('CoincidentCounter1,CoincidentCounter2;CoincidentEnergyHits',
+                                        path = 'MBTS/Cell', type='TH2F', labels = labelsCoincidentMBTS,
+                                        title = 'Run ' + run + ': Coincident Hits (energy) between two MBTS counters',
+                                        xbins = numberOfMBTS, xmin = 0, xmax = numberOfMBTS,
+                                        ybins = numberOfMBTS, ymin = 0, ymax = numberOfMBTS)
+
+
+
+    # 10) Configure histogram with Tile readout errors for MBTS counters
+    errorLabels = ['General', 'Global CRC', 'ROD CRC', 'Frontend CRC', 'BCID', 'Header Format',
+                   'Header Parity', 'Sample Format', 'Sample Parity', 'Memory Parity']
+    numberOfErrors = len(errorLabels)
+    errorLabelsMBTS = labelsMBTS + errorLabels
+    errorsGroup = helper.addGroup(tileMBTSMonAlg, 'TileErrorsMBTS', 'Tile')
+    errorsGroup.defineHistogram('ErrorCounter,Error;ReadOutErrors',
+                                path = 'MBTS/Digit', type='TH2F', labels = errorLabelsMBTS,
+                                title = 'Run ' + run + ': Tile Readout Errors for MBTS counters',
+                                xbins = numberOfMBTS, xmin = 0, xmax = numberOfMBTS,
+                                ybins = numberOfErrors, ymin = 0, ymax = numberOfErrors)
+
+
+
+    if fillHistogramPerMBTS:
+
+        # 11) Configure histogram with MBTS counter energy
+        energyArray = helper.addArray([numberOfMBTS], tileMBTSMonAlg, 'TileEnergyMBTS', topPath = 'Tile/MBTS')
+        for postfix, tool in energyArray.Tools.items():
+            mbtsCounter = int( postfix.split('_')[1] )
+            mbtsName = labelsMBTS[mbtsCounter]
+            title = 'Run ' + run + ': Energy of ' + mbtsName + ';Energy [pC]'
+            name = 'Energy;Energy_' + mbtsName
+            tool.defineHistogram(name, title = title, type = 'TH1F', path = 'Cell',
+                                 xbins = 400, xmin = -0.5, xmax = 80)
+
+        # 12) Configure histogram with MBTS counter energy vs luminosity block
+        energyLBArray = helper.addArray([numberOfMBTS], tileMBTSMonAlg, 'TileEnergyLBMBTS', topPath = 'Tile/MBTS')
+        for postfix, tool in energyLBArray.Tools.items():
+            mbtsCounter = int( postfix.split('_')[1] )
+            mbtsName = labelsMBTS[mbtsCounter]
+            title = 'Run ' + run + ': Energy of ' + mbtsName + ' per lumiblock;Lumiblocks;Energy [pC]'
+            name = 'lumiBlock,Energy;EnergyLB_' + mbtsName
+            tool.defineHistogram(name, title = title, type = 'TProfile', path = 'Cell',
+                                 xbins = 1000, xmin = -0.5, xmax = 999.5)
+
+        # 13) Configure histogram with MBTS counter time
+        timeArray = helper.addArray([numberOfMBTS], tileMBTSMonAlg, 'TileTimeMBTS', topPath = 'Tile/MBTS')
+        for postfix, tool in timeArray.Tools.items():
+            mbtsCounter = int( postfix.split('_')[1] )
+            mbtsName = labelsMBTS[mbtsCounter]
+            title = 'Run ' + run + ': Time of ' + mbtsName + ';Time [ns]'
+            name = 'Time;Time_' + mbtsName
+            tool.defineHistogram(name, title = title, type = 'TH1F', path = 'Cell',
+                                 xbins = 151, xmin = -75.5, xmax = 75.5)
+
+        # 14) Configure histogram with MBTS counter pedestal
+        pedestalArray = helper.addArray([numberOfMBTS], tileMBTSMonAlg, 'TilePedestalMBTS', topPath = 'Tile/MBTS')
+        for postfix, tool in pedestalArray.Tools.items():
+            mbtsCounter = int( postfix.split('_')[1] )
+            mbtsName = labelsMBTS[mbtsCounter]
+            title = 'Run ' + run + ': Pedestal of ' + mbtsName + ';Channel pedestal in ADC counts'
+            name = 'Pedestal;Pedestal_' + mbtsName
+            tool.defineHistogram(name, title = title, type = 'TH1F', path = 'Digit',
+                                 xbins = 100, xmin = 20.5, xmax = 120.5)
+
+        # 15) Configure histogram with high frequency noise of MBTS counter
+        hfnArray = helper.addArray([numberOfMBTS], tileMBTSMonAlg, 'TileHFNoiseMBTS', topPath = 'Tile/MBTS')
+        for postfix, tool in hfnArray.Tools.items():
+            mbtsCounter = int( postfix.split('_')[1] )
+            mbtsName = labelsMBTS[mbtsCounter]
+            title = 'Run ' + run + ': High Frequency Noise of ' + mbtsName + ';Inter-sample RMS in ADC counts'
+            name = 'HFN;HFN_' + mbtsName
+            tool.defineHistogram(name, title = title, type = 'TH1F', path = 'Digit',
+                                 xbins = 100, xmin = 0, xmax = 5)
+
+        # 16) Configure histogram with average pulse shape of MBTS counter
+        averagePulseArray = helper.addArray([numberOfMBTS], tileMBTSMonAlg, 'TileAveragePulseMBTS', topPath = 'Tile/MBTS')
+        for postfix, tool in averagePulseArray.Tools.items():
+            mbtsCounter = int( postfix.split('_')[1] )
+            mbtsName = labelsMBTS[mbtsCounter]
+            title = 'Run ' + run + ': Average Pulse for digitized signals of ' + mbtsName
+            title += ';TileCal Digital Sample;Average number of ADC counts'
+            name = 'SampleNumbers,Samples;AveragePulse_' + mbtsName
+            tool.defineHistogram(name, title = title, type = 'TProfile', path = 'Digit',
+                                 xbins = 7, xmin = -0.5, xmax = 6.5)
+
+
+
+    accumalator = helper.result()
+    result.merge(accumalator)
+    return result
+
+if __name__=='__main__':
+
+    # Setup the Run III behavior
+    from AthenaCommon.Configurable import Configurable
+    Configurable.configurableRun3Behavior = True
+
+    # Setup logs
+    from AthenaCommon.Logging import log
+    from AthenaCommon.Constants import INFO
+    log.setLevel(INFO)
+
+    # Set the Athena configuration flags
+    from AthenaConfiguration.AllConfigFlags import ConfigFlags
+
+    from AthenaConfiguration.TestDefaults import defaultTestFiles
+    ConfigFlags.Input.Files = defaultTestFiles.ESD
+    ConfigFlags.Output.HISTFileName = 'TileMBTSMonitorOutput.root'
+    ConfigFlags.lock()
+
+    # Initialize configuration object, add accumulator, merge, and run.
+    from AthenaConfiguration.MainServicesConfig import MainServicesSerialCfg
+    from AthenaPoolCnvSvc.PoolReadConfig import PoolReadCfg
+    cfg = MainServicesSerialCfg()
+    cfg.merge(PoolReadCfg(ConfigFlags))
+
+    cfg.merge( TileMBTSMonitoringConfig(ConfigFlags, TileDigitsContainer = 'TileDigitsFlt') )
+
+    cfg.printConfig(withDetails = True, summariseProps = True)
+    ConfigFlags.dump()
+
+    cfg.store( open('TileMBTSMonitorAlgorithm.pkl','w') )
+
+    sc = cfg.run(maxEvents=3)
+
+    import sys
+    # Success should be 0
+    sys.exit(not sc.isSuccess())
diff --git a/TileCalorimeter/TileMonitoring/src/TileMBTSMonitorAlgorithm.cxx b/TileCalorimeter/TileMonitoring/src/TileMBTSMonitorAlgorithm.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..2099c12e685e0fdcf866ce422b988b964908719a
--- /dev/null
+++ b/TileCalorimeter/TileMonitoring/src/TileMBTSMonitorAlgorithm.cxx
@@ -0,0 +1,337 @@
+/*
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "TileMBTSMonitorAlgorithm.h"
+
+#include "TileIdentifier/TileHWID.h"
+#include "TileIdentifier/TileFragHash.h"
+
+#include "CaloIdentifier/TileTBID.h"
+
+#include "StoreGate/ReadHandle.h"
+
+
+StatusCode TileMBTSMonitorAlgorithm::initialize() {
+
+  ATH_CHECK( AthMonitorAlgorithm::initialize() );
+
+  ATH_MSG_INFO("in initialize()");
+
+  if (m_energyCut.size() != MAX_MBTS_COUNTER) {
+    int numberOfCounters{MAX_MBTS_COUNTER};
+    ATH_MSG_ERROR("Energy cuts are not provided for all ("
+                  << numberOfCounters << ") MBTS. Provided only "
+                  << m_energyCut.size() << " energy cuts");
+
+    return StatusCode::FAILURE;
+  }
+
+  ATH_CHECK( m_cablingSvc.retrieve() );
+  m_cabling = m_cablingSvc->cablingService();
+
+  ATH_CHECK( detStore()->retrieve(m_tileTBID) );
+  ATH_CHECK( detStore()->retrieve(m_tileHWID) );
+
+  ATH_CHECK( m_DQstatusKey.initialize() );
+  ATH_CHECK( m_digitsContainerKey.initialize() );
+  ATH_CHECK( m_mbtsCellContainerKey.initialize() );
+
+  memset(m_MBTSchannels, -1, sizeof(m_MBTSchannels));
+  memset(m_MBTScounters, -1, sizeof(m_MBTScounters));
+  for (unsigned int ros = 3; ros < Tile::MAX_ROS ; ++ros) {
+    for (unsigned int drawer = 0; drawer < Tile::MAX_DRAWER; ++drawer) {
+      HWIdentifier drawerHWID = m_tileHWID->drawer_id(ros, drawer);
+      Identifier mbtsID = m_cabling->drawer2MBTS_id(drawerHWID);
+      if (mbtsID.is_valid()) {
+        int channel = m_tileHWID->channel(m_cabling->s2h_channel_id(mbtsID));
+        m_MBTSchannels[ros - 3][drawer] = channel;
+
+        int counter = getMBTSCounter(mbtsID);
+        m_MBTScounters[ros - 3][drawer] = counter;
+
+        ATH_MSG_DEBUG( "Found MBTS: drawer/channel (counter)=> " << drawer << "/" << channel << "(" << counter << ")" );
+
+      }
+    }
+  }
+
+
+  m_energyGroups = Monitored::buildToolMap<int>(m_tools, "TileEnergyMBTS", MAX_MBTS_COUNTER);
+  m_energyLBGroups = Monitored::buildToolMap<int>(m_tools, "TileEnergyLBMBTS", MAX_MBTS_COUNTER);
+
+  m_timeGroups = Monitored::buildToolMap<int>(m_tools, "TileTimeMBTS", MAX_MBTS_COUNTER);
+
+  m_hfnGroups = Monitored::buildToolMap<int>(m_tools, "TileHFNoiseMBTS", MAX_MBTS_COUNTER);
+  m_pedestalGroups = Monitored::buildToolMap<int>(m_tools, "TilePedestalMBTS", MAX_MBTS_COUNTER);
+
+  m_pulseGroups = Monitored::buildToolMap<int>(m_tools, "TileAveragePulseMBTS", MAX_MBTS_COUNTER);
+
+  return StatusCode::SUCCESS;
+}
+
+
+StatusCode TileMBTSMonitorAlgorithm::fillHistograms( const EventContext& ctx ) const {
+
+  // In case you want to measure the execution time
+  auto timer = Monitored::Timer("TIME_execute");
+  auto lumiBlock = Monitored::Scalar<int>("lumiBlock", GetEventInfo(ctx)->lumiBlock());
+
+  int nHitsA(0);
+  int nHitsC(0);
+  double timeA(0.0);
+  double timeC(0.0);
+
+  auto monEnergy = Monitored::Scalar<float>("Energy", 0.0F);
+  auto monTime = Monitored::Scalar<float>("Time", 0.0F);
+
+  std::vector<float> energyCounters;
+  auto monEnergyCounter = Monitored::Collection("EnergyCounter", energyCounters);
+
+  std::vector<float> energies;
+  auto monSummaryEnergy = Monitored::Collection("SummaryEnergy", energies);
+
+  std::vector<float> timeCounters;
+  auto monTimeCounter = Monitored::Collection("TimeCounter", timeCounters);
+
+  std::vector<float> times;
+  auto monSummaryTime = Monitored::Collection("SummaryTime", times);
+
+  std::vector<int> energyHitCounters;
+
+  SG::ReadHandle<TileCellContainer> mbtsContainer(m_mbtsCellContainerKey, ctx);
+  ATH_CHECK( mbtsContainer.isValid() );
+
+  for (const TileCell* cell : *mbtsContainer) {
+
+    Identifier id = cell->ID();
+
+    // Calculate MBTS counter from "side", "tower" and "module"
+    // Counter goes 0-31.
+    // EBA-inner:0-7,EBA-outer:8-15,EBC-inner:16-23,EBC-outer:24-31
+    // tower is 1 for outer counter (lower eta) and 0 for inner counter (higher eta)
+    // module counts from 0-7 in increasing phi
+    // side is -1 for EBC 1 for EBA
+
+    int counter = getMBTSCounter(id);
+    energyCounters.push_back(counter);
+
+    double energy = cell->energy();
+    monEnergy = energy;
+    energies.push_back(energy);
+
+    double time = cell->time();
+    monTime = time;
+
+    float quality = cell->quality();
+
+    ATH_MSG_VERBOSE("Counter: " << counter
+                    << ", energy= " << energy << " pCb"
+                    << ", time= " << time
+                    << ", quality= " << quality);
+
+
+    if (m_fillHistogramsPerMBTS) {
+      fill(m_tools[m_energyGroups[counter]], monEnergy);
+      fill(m_tools[m_energyLBGroups[counter]], lumiBlock, monEnergy);
+    }
+
+    if (energy > m_energyCut[counter]) {
+
+      timeCounters.push_back(counter);
+      times.push_back(time);
+
+      energyHitCounters.push_back(counter);
+
+      if (m_fillHistogramsPerMBTS) {
+        fill(m_tools[m_timeGroups[counter]], monTime);
+      }
+
+      if (std::abs(time) > 10e-4) {
+        if (counter < 16) { // MBTS A side
+          timeA += time;
+          ++nHitsA;
+        } else { // MBTS C side
+          timeC += time;
+          ++nHitsC;
+        }
+      }
+
+    }
+  }
+
+
+  fill("TileOccupancyMBTS", monEnergyCounter, monSummaryEnergy);
+  fill("TileEnergySummaryMBTS", monEnergyCounter, monSummaryEnergy);
+
+  fill("TileTimeSummaryMBTS", monTimeCounter, monSummaryTime);
+
+  if (nHitsA > 0) {
+    timeA /= nHitsA;
+    auto monTimeA = Monitored::Scalar<float>("TimeA", timeA);
+    fill("TileTimeMBTSA", monTimeA);
+  }
+
+  if (nHitsC > 0) {
+    timeC /= nHitsC;
+    auto monTimeC = Monitored::Scalar<float>("TimeC", timeC);
+    fill("TileTimeMBTSC", monTimeC);
+  }
+
+  if (nHitsA > 0 && nHitsC > 0) {
+    double timeDifference = timeA - timeC;
+    auto monTimeDifference = Monitored::Scalar<float>("TimeDifference", timeDifference);
+    fill("TileTimeDifferenceMBTS", monTimeDifference);
+    fill("TileTimeDifferenceMBTSLB", lumiBlock, monTimeDifference);
+  }
+
+
+  std::vector<int> coincidentCounters1;
+  auto monCoincidentCounters1 = Monitored::Collection("CoincidentCounter1", coincidentCounters1);
+
+  std::vector<int> coincidentCounters2;
+  auto monCoincidentCounters2 = Monitored::Collection("CoincidentCounter2", coincidentCounters2);
+
+  for (int counter1 : energyHitCounters) {
+    for (int counter2 : energyHitCounters) {
+      coincidentCounters1.push_back(counter1);
+      coincidentCounters2.push_back(counter2);
+    }
+  }
+
+  fill("TileCoincidentHitsMBTS", monCoincidentCounters1, monCoincidentCounters2);
+
+  std::vector<int> errors;
+  auto monErrors = Monitored::Collection("Error", errors);
+
+  std::vector<int> counters;
+  auto monErrorCounters = Monitored::Collection("ErrorCounter", counters);
+
+  auto monPedestal = Monitored::Scalar<float>("Pedestal", 0.0F);
+  auto monHFN = Monitored::Scalar<float>("HFN", 0.0F);
+
+  // Create instance of TileDQstatus used to check for readout errors in Tile
+  const TileDQstatus * dqStatus = SG::makeHandle (m_DQstatusKey, ctx).get();
+
+  SG::ReadHandle<TileDigitsContainer> digitsContainer(m_digitsContainerKey, ctx);
+  ATH_CHECK( digitsContainer.isValid() );
+
+  for (const TileDigitsCollection* digitsCollection : *digitsContainer) {
+    HWIdentifier adc_id = digitsCollection->front()->adc_HWID();
+    int ros = m_tileHWID->ros(adc_id);
+    if (ros > 2) { // Extended barrel
+      int drawer = m_tileHWID->drawer(adc_id);
+      int MBTSchannel = m_MBTSchannels[ros - 3][drawer];
+
+      if (MBTSchannel >= 0) {
+        for (const TileDigits* tile_digits: *digitsCollection) {
+
+          adc_id = tile_digits->adc_HWID();
+          int channel = m_tileHWID->channel(adc_id);
+          if (channel == MBTSchannel) {  // MBTS channel found
+            int gain = m_tileHWID->adc(adc_id);
+            int counter = m_MBTScounters[ros - 3][drawer];
+
+            // Fill Readout Error histogram
+            const int dmu = 0;
+            if (!(dqStatus->isChanDQgood(ros, drawer, channel))) {
+              setDigiError(counters, errors, counter, GENERAL);
+            }
+            if (dqStatus->checkGlobalCRCErr(ros, drawer, gain)) {
+              setDigiError(counters, errors, counter, GLOBAL_CRC);
+            }
+            if (dqStatus->checkROD_CRCErr(ros, drawer, dmu, gain)) {
+              setDigiError(counters, errors, counter, ROD_CRC);
+            }
+            if (dqStatus->checkFE_CRCErr(ros, drawer, dmu, gain)) {
+              setDigiError(counters, errors, counter, FRONTEND_CRC);
+            }
+            if (dqStatus->checkBCIDErr(ros, drawer, dmu, gain)) {
+              setDigiError(counters, errors, counter, BCID);
+            }
+            if (dqStatus->checkHeaderFormatErr(ros, drawer, dmu, gain)) {
+              setDigiError(counters, errors, counter, HEADER_FORMAT);
+            }
+            if (dqStatus->checkHeaderParityErr(ros, drawer, dmu, gain)) {
+              setDigiError(counters, errors, counter, HEADER_PARITY);
+            }
+            if (dqStatus->checkSampleFormatErr(ros, drawer, dmu, gain)) {
+              setDigiError(counters, errors, counter, SAMPLE_FORMAT);
+            }
+            if (dqStatus->checkSampleParityErr(ros, drawer, dmu, gain)) {
+              setDigiError(counters, errors, counter, SAMPLE_PARITY);
+            }
+            if (dqStatus->checkMemoryParityErr(ros, drawer, dmu, gain)) {
+              setDigiError(counters, errors, counter, MEMORY_PARITY);
+            }
+
+
+            if (m_fillHistogramsPerMBTS) {
+
+              double sampleMean = 0;
+              double sampleRMS = 0;
+
+              std::vector<float> samples = tile_digits->samples();
+              unsigned int nSamples = samples.size();
+              if (nSamples > 0) {
+
+                for (float sample : samples) {
+                  sampleMean += sample;
+                  sampleRMS += sample * sample;
+                }
+
+                auto min_max = std::minmax_element(samples.begin(), samples.end());
+                float minSample = *min_max.first;
+                float maxSample = *min_max.second;
+
+                if ((maxSample - minSample) > 10) {
+
+                  auto monSamples = Monitored::Collection("Samples", samples);
+
+                  std::vector<int> sampleNumbers;
+                  for (unsigned int i = 0; i < nSamples; ++i) sampleNumbers.push_back(i);
+                  auto monSampleNumbers = Monitored::Collection("SampleNumbers", sampleNumbers);
+
+                  fill(m_tools[m_pulseGroups[counter]], monSampleNumbers, monSamples);
+                }
+
+                sampleMean /= nSamples;
+                sampleRMS = sampleRMS / nSamples - sampleMean * sampleMean;
+                sampleRMS = (sampleRMS > 0.0 && nSamples > 1u) ? sqrt(sampleRMS * nSamples / (nSamples - 1u)) : 0.0;
+
+                monHFN = sampleRMS;
+                fill(m_tools[m_hfnGroups[counter]], monHFN);
+
+                monPedestal = samples.front();
+                fill(m_tools[m_pedestalGroups[counter]], monPedestal);
+
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+
+  fill("TileErrorsMBTS", monErrorCounters, monErrors);
+
+  fill("TileMBTSMonExecuteTime", timer);
+
+  return StatusCode::SUCCESS;
+}
+
+
+
+int TileMBTSMonitorAlgorithm::getMBTSCounter(Identifier mbtsID) const {
+  int counter = m_tileTBID->phi(mbtsID) + 8 * m_tileTBID->eta(mbtsID);
+  if (m_tileTBID->side(mbtsID) < 0) counter += 16;// EBC side
+  return counter;
+}
+
+
+void TileMBTSMonitorAlgorithm::setDigiError(std::vector<int>& counters, std::vector<int>& errors,
+                                            int counter, int error) const {
+
+  counters.push_back(counter);
+  errors.push_back(error);
+}
diff --git a/TileCalorimeter/TileMonitoring/src/TileMBTSMonitorAlgorithm.h b/TileCalorimeter/TileMonitoring/src/TileMBTSMonitorAlgorithm.h
new file mode 100644
index 0000000000000000000000000000000000000000..d97ae4ab22aee904486a25c06ed5ef9424b022b5
--- /dev/null
+++ b/TileCalorimeter/TileMonitoring/src/TileMBTSMonitorAlgorithm.h
@@ -0,0 +1,102 @@
+/*
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TILEMONITORING_TILEMBTSMONITORALGORITHM_H
+#define TILEMONITORING_TILEMBTSMONITORALGORITHM_H
+
+#include "TileEvent/TileContainer.h"
+#include "TileEvent/TileDigitsContainer.h"
+#include "TileEvent/TileDQstatus.h"
+#include "TileConditions/TileCablingSvc.h"
+#include "TileCalibBlobObjs/TileCalibUtils.h"
+
+#include "AthenaMonitoring/AthMonitorAlgorithm.h"
+#include "AthenaMonitoring/Monitored.h"
+
+#include "StoreGate/ReadHandleKey.h"
+#include "GaudiKernel/ServiceHandle.h"
+
+
+class TileTBID;
+class TileHWID;
+class TileCablingService;
+
+/** @class TileMBTSMonitorAlgorithm
+ *  @brief Class for Tile MBTS based monitoring
+ */
+
+class TileMBTSMonitorAlgorithm : public AthMonitorAlgorithm {
+
+  public:
+
+    using AthMonitorAlgorithm::AthMonitorAlgorithm;
+
+    virtual ~TileMBTSMonitorAlgorithm() = default;
+    virtual StatusCode initialize() override;
+    virtual StatusCode fillHistograms( const EventContext& ctx ) const override;
+
+  private:
+
+    using Tile = TileCalibUtils;
+
+    enum TileDigiErrors {GENERAL, GLOBAL_CRC, ROD_CRC, FRONTEND_CRC, BCID, HEADER_FORMAT,
+                         HEADER_PARITY, SAMPLE_FORMAT, SAMPLE_PARITY, MEMORY_PARITY};
+
+    void setDigiError(std::vector<int>& counters, std::vector<int>& errors, int counter, int error) const;
+
+    int getMBTSCounter(Identifier mbtsID) const;
+
+    Gaudi::Property<bool> m_fillHistogramsPerMBTS{this,
+        "FillHistogramsPerMBTS", true, "Switch for using per MBTS histograms"};
+
+    Gaudi::Property<std::vector<float>> m_energyCut{this,
+        "EnergyCuts",
+         {//MBTSA00   MBTSA01   MBTSA02   MBTSA03   MBTSA04   MBTSA05   MBTSA06   MBTSA07
+           60. /222, 60. /222, 60. /222, 60. /222, 60. /222, 60. /222, 60. /222, 60. /222,
+          //MBTSA08   MBTSA09   MBTSA10   MBTSA11   MBTSA12   MBTSA13   MBTSA14   MBTSA15
+           60. /222, 60. /222, 60. /222, 60. /222, 60. /222, 60. /222, 60. /222, 60. /222,
+          //MBTSC00   MBTSC01   MBTSC02   MBTSC03   MBTSC04   MBTSC05   MBTSC06   MBTSC07
+           60. /222, 60. /222, 60. /222, 60. /222, 60. /222, 60. /222, 60. /222, 60. /222,
+          //MBTSC08   MBTSC09   MBTSC10   MBTSC11   MBTSC12   MBTSC13   MBTSC14   MBTSC15
+           60. /222, 60. /222, 60. /222, 60. /222, 60. /222, 60. /222, 60. /222, 60. /222},
+        "Energy cuts for 32 MBTS counters (MBTSA00, .., MBTSC15)"};
+
+    SG::ReadHandleKey<TileDQstatus> m_DQstatusKey{this,
+        "TileDQstatus", "TileDQstatus", "Tile DQ status"};
+
+    SG::ReadHandleKey<TileDigitsContainer> m_digitsContainerKey{ this,
+        "TileDigitsContainer", "TileDigitsCnt", "Tile digits container" };
+
+    SG::ReadHandleKey<TileCellContainer> m_mbtsCellContainerKey{this,
+        "MBTSContainer", "MBTSContainer", "Tile MBTS container" };
+
+    /**
+     * @brief Name of Tile cabling service
+     */
+    ServiceHandle<TileCablingSvc> m_cablingSvc{this,
+        "TileCablingSvc", "TileCablingSvc", "The Tile cabling service" };
+
+    const TileCablingService* m_cabling{nullptr};
+
+    std::vector<int> m_energyGroups;
+    std::vector<int> m_energyLBGroups;
+
+    std::vector<int> m_timeGroups;
+
+    std::vector<int> m_hfnGroups;
+    std::vector<int> m_pedestalGroups;
+
+    std::vector<int> m_pulseGroups;
+
+
+    const TileTBID* m_tileTBID{nullptr};
+    const TileHWID* m_tileHWID{nullptr};
+
+    int m_MBTSchannels[Tile::MAX_ROS - 3][Tile::MAX_DRAWER];
+    int m_MBTScounters[Tile::MAX_ROS - 3][Tile::MAX_DRAWER];
+
+    static const unsigned int MAX_MBTS_COUNTER{32};
+};
+
+#endif // TILEMONITORING_TILEMBTSMONITORALGORITHM_H
diff --git a/TileCalorimeter/TileMonitoring/src/components/TileMonitoring_entries.cxx b/TileCalorimeter/TileMonitoring/src/components/TileMonitoring_entries.cxx
index 54ca7e4e40da38755b974abafe7c124205593f81..0feaf7f983a4995d1e8495db780b82f2cca1614c 100644
--- a/TileCalorimeter/TileMonitoring/src/components/TileMonitoring_entries.cxx
+++ b/TileCalorimeter/TileMonitoring/src/components/TileMonitoring_entries.cxx
@@ -24,6 +24,7 @@
 #include "TileMonitoring/TileTBCellMonTool.h"
 #include "../TileJetMonitorAlgorithm.h"
 #include "../TileDQFragMonitorAlgorithm.h"
+#include "../TileMBTSMonitorAlgorithm.h"
 
 DECLARE_COMPONENT( TileFatherMonTool )
 DECLARE_COMPONENT( TilePaterMonTool )
@@ -51,4 +52,5 @@ DECLARE_COMPONENT( TileTBMonTool )
 DECLARE_COMPONENT( TileTBCellMonTool )
 DECLARE_COMPONENT( TileJetMonitorAlgorithm )
 DECLARE_COMPONENT( TileDQFragMonitorAlgorithm )
+DECLARE_COMPONENT( TileMBTSMonitorAlgorithm )